Re: [eigen] What is the 'correct' way to pass matrix results?

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


Hi Christoph,

There is no single correct solution. It depends on your requirements
and your working environment.

On Wed, May 18, 2011 at 12:43 PM, Christoph Hertzberg
<chtz@xxxxxxxxxxxxxxxxxxxxxxxx> wrote:
> 1) Implement an expression template -- this might be ok if your code is
>   in pre-final stage ... or if you return using C++0x auto return type;
>   otherwise, I think it is a bit too complicated.

I agree, that writing an expression is quite complicated but I
disagree that using an expression is complicated. Its usage gets only
complicated, when you try to store the expression into a temporary
which is not a PlainObject, i.e. when you exactly need to know the
type of an expression. In most cases you probably do not need this
knowledge.

This solution is efficient, generic, portable and depending on your
hand-written expression const-correct while being complicated.

> 2) Pass output parameters by values, inline everything and rely on your
>   compiler to optimize away unnecessary overhead. I think this works
>   reasonably well for small types, I experienced some overhead when
>   assigning vectorized expressions to unaligned destinations, though.

In case we are talking about expressions, they are always returned by
value. The difficulty is that such expressions may be complex
constructs consisting of several other nested expressions. Thus their
return types are complicated or at least cumbersome to define.

In case we are returning an Eigen PlainObject (Matrix or Array), it
can only be optimized away, as long as it is not dynamic. For dynamic
matrices there will always be at least one copy (ignoring std::move
features from C++0x, see bug #266 for details).

This solution is partly efficient (for fixed size types), portable,
const-correct and simple while being not generic. In fact, even with
C++0x features, this solution would always be only partially
efficient, since it will always introduce temporaries when assigning
to other expressions.

> 3) Pass a Matrix<...> by reference. This does not work when assigning
>   to a block or similar.

As you observed, this approach is not generic but it is efficient,
portable, safe and easy to implement.

> 4) Pass a const MatrixBase<...>& as proposed here [1] and const_cast
>   it. Obvious drawback of this is that it easily bypasses const-
>   correctness (actually only for plain matrices, not for blocks/maps).

This is quite a hack and we always said so but ... it is an efficient,
generic, portable and easy solution though not safe.

Now, let's assume you develop in an environment, where you have access
to C++0x and let's furthermore assume that your code is never intended
to be compiled on a non C++0x system.

A) Pass the output by r-value reference:

template <typename Derived>
void foo(MatrixBase<Derived>&& output) {}

This solution is efficient, generic, safe, easy to implement but not portable.

To truly answer your question, one would need to know the exact use
case and usage constraints.

HTH,
Hauke



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