ArrayXXf::matrix().applyOnTheLeft(...) trips assertions

Submitted by Rhys Ulerich

Assigned to Nobody

Link to original bugzilla bug (#817)
Version: 3.2

Description

The following works in Eigen 3.2.1:

VectorXf x = VectorXf::Random(48);
MatrixXf A = MatrixXf::Random(48, 6);
A.applyOnTheLeft(x.transpose());

This continuation, which looks equivalent, trips assertions in
DenseBase<Derived>::lazyAssign:

ArrayXXf B = ArrayXXf::Random(48, 6);
B.matrix().applyOnTheLeft(x.transpose());

Originally reported in http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2014/05/msg00021.html in which Christoph gave some insight:

--8<--
This does work:
B = (x.transpose()*B.matrix()).eval();

I seems the problem is that assigning a product to an array does not set the NeedEvalBeforeAssignment flag (which generally is not required for Array operations). This leads to B getting resized before the product is evaluated which evidently is a problem.
I'd say this is a bug in Eigen, not a usage error on your side!

The problem with B.matrix().applyOnTheLeft(...) and similar is that .matrix() expressions are writable but not resizable -- I'm not sure if this is by design. But it is similar to Maps which are not resizable either:

// only works if no resizing is needed:
Map<MatrixXf>(data, 48, 6).applyOnTheLeft(...);

We could make a more clear run-time assertion message for these cases.
E.g. "Operation requires resizing a non-resizable expression"
--8<--

The continuation of that thread, including Christoph's comments, might require going to http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2014/06/maillist.html as the month changed in the interim.

Blocking

#558 (closed)

Edited by Eigen Bugzilla