New user self-registration is disabled due to spam. Please email eigen-core-team @ lists.tuxfamily.org if you need an account.
Bug 822 - Outer products assume vectors provide linear access
Summary: Outer products assume vectors provide linear access
Status: RESOLVED FIXED
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - matrix products (show other bugs)
Version: 3.2
Hardware: All All
: Normal Compilation Problem
Assignee: Nobody
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 3.3
  Show dependency treegraph
 
Reported: 2014-06-06 10:29 UTC by Jitse Niesen
Modified: 2014-09-08 10:23 UTC (History)
2 users (show)



Attachments

Description Jitse Niesen 2014-06-06 10:29:16 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 row(1,5); 
      Eigen::VectorXd col(3); 
      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 

      Eigen::MatrixXd col(3,1); 

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?
Comment 1 Christoph Hertzberg 2014-06-06 13:58:57 UTC
(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.
Comment 2 Gael Guennebaud 2014-09-08 10:23:36 UTC
Calling coeff(0,j) is indeed harmless:

https://bitbucket.org/eigen/eigen/commits/cfef8b0e7294/
Changeset:   cfef8b0e7294
User:        ggael
Date:        2014-09-08 10:21:22
Summary:     Fix bug 822: outer products needed linear access, and add respective unit tests

https://bitbucket.org/eigen/eigen/commits/5bb9e20d2fb8/

Note You need to log in before you can comment on or make changes to this bug.