[eigen] giving up on Generic; proposed simpler solution

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


Hi List,

Finally I don't think anymore that the idea of Generic was good.

The idea was to improve the API so that instead of doing

matrix.dynBlock(a,b,c,d) = DynBlock<MatrixType>::zero(c,d);

or

matrix.dynBlock(a,b,c,d) = matrix.dynBlock(a,b,c,d).zero(c,d);

one could simply do

matrix.dynBlock(a,b,c,d) = Eigen::zero();

The first problem is that zero() would still need to know the scalar type, 
unless we do automatic type promotion. So that would be

matrix.dynBlock(a,b,c,d) = Eigen::zero<Scalar>(c,d);

which already defeats part of the point of Generic.

In addition to all the good reasons we already have to NOT do automatic type 
promotion (complexity, overhead, not the behaviour of POD types) I just found 
one more: for std::complex, doing a static_cast to same type can easily 
result in a copy! Of course POD types are not subject to that problem. 
However we want to support std::complex as much as possible so we don't want 
to pay that cost. This means that doing acceptable automatic type promotion 
in our case would be really especially complex.

Then, I thought about how to implement the Generic size, and the fact is, it 
means a lot more complexity all over the place.

Then it occured to me that there is a much simpler solution. Let's not blindly 
do elegant things just for the sake of it: sometimes the simpler solution is 
better! So let's do like in Eigen1, let's add MatrixBase::setZero(). In 
Eigen2 it's just as quick to implement; the difference here is that, combined 
to the power of expression templates, it becomes much more powerful:

matrix.dynBlock(a,b,c,d).setZero();

This is the cleanest solution, isn't it?

Of course the Zero expression remains for when it's what one wants, like

Matrix3d m = Matrix3d::zero();

To Jonas: I am also considering adding a corner() method as a special case of 
block, since it is so commonly used. So you will be able to do e.g.

B.corner(i, j, Eigen::BottomRight) = A.corner(i, j, Eigen::BottomRight);

I will also overload all these functions for vectors so that it's not 
necessary to pass redundant arguments for vectors.

Cheers,

Benoit

Attachment: signature.asc
Description: This is a digitally signed message part.



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