Re: [eigen] calculating on ranges |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] calculating on ranges
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Tue, 27 Jan 2009 14:06:48 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=P6O5oD4A11dyFvFcfLmxo9rXdyr7eaClaTGiAhvCHa4=; b=TsP44pBkAeJe8xGDrKPqYgtoiJsmH+49R9Pa+8HJH1VuC4T3al4vpr9NRsygAruYa0 mVXwoRvVXEAjvlpSWpKfUPv+f1Ni0XcCVB+DQbZNkCofxr1CGVKBQa2WTwtZhRdhNi84 TqwtdLOD8epP3mRMqN+AeMch4azlkdx4z2SDY=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=aegigEB5/t9nGRTENlZ3E5sY8qDx1GrdbQzMRyLBKW3bZWUMPIUCB2/PI8LPvHt1bB dlzd8YvudKgJILiEY2lZhKBskfphM0FI9fVWnjlAMz5wwQHHcgHcVzgXGm1KCISOa63N sY6ncu3g1qNMDmHX7VAkD34IdRGjQ6/o6ruz4=
OOps there is a big constness problem, I marked y as const but then I modify it.
However, in order to allow passing a temporary xpr as y, I have to
make it const. So again the solution is a const_cast, yes that's ugly
but the C++ language leaves us no choice if we want to pass a
temporary segment() as y.
template<typename VectorType>
void addGaussianToCurve(
const MatrixBase<VectorType>& x,
const MatrixBase<VectorType>& _y,
typename VectorType::Scalar a,
typename VectorType::Scalar b,
typename VectorType::Scalar c)
{
VectorType& y = _y.const_cast_derived();
y += a * ( -(x.cwise() - b).cwise().square() / c ).cwise().exp();
}
Cheers,
Benoit
2009/1/27 Benoit Jacob <jacob.benoit.1@xxxxxxxxx>:
> Hi,
>
> Yes, Eigen's lazy evaluation means that if you implement this with
> Eigen it will also evaluate the function only on the range that's
> needed.
>
> Compared to your C function, I don't know if you would prefer the
> Eigen way or not. Normally, Eigen would bring the advantage of
> vectorization, except that here you use exp and that is not yet
> vectorized (it could be if that were important. we would use Pade
> approximants if there are no SSE instructions for that.). The other
> advantage of using Eigen is that it will automatically unroll the loop
> if the size (here 10) is known at compile-time and the total cost
> isn't too big (you can tune EIGEN_UNROLLING_LIMIT).
>
> Here is a basic Eigen implementation:
>
> #include <Eigen/Array>
>
> template<typename VectorType>
> void addGaussianToCurve(
> const MatrixBase<VectorType>& x,
> const MatrixBase<VectorType>& y,
> typename VectorType::Scalar a,
> typename VectorType::Scalar b,
> typename VectorType::Scalar c)
> {
> y += a * ( -(x.cwise() - b).cwise().square() / c ).cwise().exp();
> }
>
> Now if you have vectors VectorXd x,y; you can call your function like this:
> addGaussianToCurve(
> x.segment(start,length),
> y.segment(start,length),
> a,b,c);
>
> Now if you know length at compile time you can do:
> addGaussianToCurve(
> x.segment<length>(start),
> y.segment<length>(start),
> a,b,c);
> And it will automatically unroll the loop if appropriate (see above).
>
> Again if vectorization matters it's no big deal, we just need a packet
> version of exp(). You'd then benefit from it automatically.
>
> Cheers,
> Benoit
>