This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
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: 2019-12-04 13: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/
Comment 3 Nobody 2019-12-04 13:23:03 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/822.

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