Re: [eigen] DenseBase::NullaryExpr - Functor requirements

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]




On Sun, Mar 13, 2016 at 11:11 AM, Dan Čermák <dan.cermak@xxxxxxxxxxxxxxxxxxx> wrote:
Hi Gael,

thanks for your answer.

If I understand this correctly, then operator()(Index) is only called when
eigen assumes that the Matrix is actually a vector. Could this happen when I
am using reductions and/or array operations?

If you call .col(j)/.row(j) on a 2D _expression_, then you end up with a vector/1D array, but that's the only case I can think of.
 
Is there some simple way how to
track down which method calls operator()(index) instead of operator()(index,
index)?

Yes, in a debugger, or at compile time by writing it like this:

template<typename T>
Scalar operator()(T i) {
  return T::fail();
}
 
this will trigger a compilation error when the function is instantiated with the complete call tree.

Concerning the vectorization, is there a simple example somewhere in the eigen
source?

yes, in src/Core/Functors/NullaryFunctors.h [1], there is a simple one returning a constant value, and a more involved one implementing linear-spacing. This one is a bit more tricky because there are two paths:
- one for random access (the standard one)
- one for sequential access which can be optimized through incremental computation (called by M.setLinSpace(...)).
 
gael

[1] https://bitbucket.org/eigen/eigen/src/774d70b529d61a35b8774c4a263e82f9261124e3/Eigen/src/Core/functors/NullaryFunctors.h?at=default&fileviewer=file-view-default


I would be happy to submit a patch, once I understand the behavior a bit
better (currently I do not feel to be able to improve anything).


Cheers,

Dan

On Friday 11 March 2016 12:11:06 Gael Guennebaud wrote:
> Hi Dan,
>
>
> Indeed, for vectors, it calls operator()(Index), as in the following
> example:
>
> http://eigen.tuxfamily.org/dox-devel/classEigen_1_1DenseBase.html#a997ef3960
> 458fb5dedb8f7f78b068a9b
>
> For really 2D matrices, operator()(Index) should not be called, otherwise
> we would need to know the storage order within the functor itself.
>
> And yes, you can also add a packet(Index{,Index}) method to enable
> vectorization.
>
> You are very welcome to propose a patch to improve the documentation
> regarding these aspects. A common adage says that documentation is better
> written by users.
>
> cheers,
> gael
>
>
> On Thu, Mar 10, 2016 at 11:41 PM, Dan Čermák <dan.cermak@xxxxxxxxxxxxxxxxxxx
> > wrote:
> >
> > Hi guys,
> >
> > I am slightly confused by the required functions for the Functors to
> > create a
> > CwiseNullaryOp using DenseBase::NullaryExpr.
> >
> > I thought it would be enough to write a struct which provides a operator()
> > (int,int) which returns the element i,j of the _expression_. However when
> > doing
> > that, I get frequent compilation errors which end with the following:
> >
> > /usr/include/eigen3/Eigen/src/Core/CwiseNullaryOp.h:82:29: error: no match
> > for
> > call to '(...)'
> >
> >        return m_functor(index)
> >
> > (... <- is an ugly template _expression_ which is my functor)
> >
> > So after some experimentation, I guessed that this operator()(int) should
> > return also the matrix elements but compressed into a 1D array. But I am
> > not
> > sure at all about that. Although I seem to get the correct result when
> > doing
> > that.
> >
> > Could you maybe point me to the documentation where this is specified
> > (sorry
> > couldn't find it)? Also is the single index operator dependent on the
> > storage
> > order of DenseBase?
> >
> > And out of curiosity, when searching the file
> > Eigen/src/Core/CwiseNullaryOp.h
> > (the compile error from above occurred there), I found a function call
> > PacketScalar. What's that about? Is this for vectorization?
> >
> >
> > Thanks in advance!
> >
> > Dan






Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/