Bugzilla – Bug 822
Outer products assume vectors provide linear access
Last modified: 2014-09-08 10:23:43 UTC
This is prompted by a post of amackey at the forum at http://forum.kde.org/viewtopic.php?f=74&t=121501 . The following code does not compile with the dev branch (this is a slight simplification of the code posted at the forum):
Eigen::MatrixXd prod = col * row.leftCols(3);
It hits the static assert YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT in MapBase.h:99 . Looking at the backtrace, Eigen recognizes the product as an outer product and thus wants to do col.coeff(i) * row.leftCols(3).coeff(j) but there is no coeff(Index) member function for row.leftCols(3) because this does not have linear access.
Rather confusingly, the code does work if col is a run-time vector; i.e. declared with
I think the solution would be for MapBase to provide a coeff(Index) member function if it is a run-time vector (i.e. either cols()=1 or rows()=1). Or would this break something somewhere?
(In reply to comment #0)
> Rather confusingly, the code does work if col is a run-time vector; i.e.
> declared with
> Eigen::MatrixXd col(3,1);
Matrix::coeff(Index i) always returns the i-th element, regardless of the dimension. I.e. even MatrixXd(3,3).coeff(i) works. That is similar to what Matlab does when indexing with a single index. I can't say that I really like this behavior, but we certainly can't forbid that anymore. I think a cleaner solution would have been to only allow
MatrixXd(n,m).vec().coeff(i) (assuming bug 712 was implemented).
> I think the solution would be for MapBase to provide a coeff(Index) member
> function if it is a run-time vector (i.e. either cols()=1 or rows()=1). Or
> would this break something somewhere?
It would not break working code, but we would lose a static assertion which prevents some accidental misuse -- at the cost of replacing it by only a run-time assertion.
How about replacing rhs().coeff(j) by rhs().coeff(0,j) in outer_product_selector_run? (And the same for lhs().coeff(i,0) in the other implementation). With coeff() being inlined this should be simple enough for all compilers to optimize away.
Calling coeff(0,j) is indeed harmless:
Date: 2014-09-08 10:21:22
Summary: Fix bug 822: outer products needed linear access, and add respective unit tests