Re: [eigen] help using foo(const MatrixBase<T>&) with (u * v)

[ Thread Index | Date Index | More Archives ]

Thank you, Gael and Christoph! That makes a lot of sense.

On Fri, Mar 13, 2015 at 4:57 PM, Gael Guennebaud <gael.guennebaud@xxxxxxxxx> wrote:

as Christoph said evaluating matrix product coefficient-wise is highly inefficient, therefore in Eigen 3 we decided to forbid coefficient accesses to product _expression_ unless this a inner product. This is what the assertion exactly does.

The following:


works because (u*v) gets evaluated into a MatrixXd temporary by the Transpose _expression_.

If you really want to evaluate the product coefficient-wise, then call:


lazyProduct returns a "true" _expression_ template.

if you are going to access to all coefficients then rather call bar like this:



On Fri, Mar 13, 2015 at 3:57 PM, Daniel Lee <bearlee@xxxxxxxxxxxx> wrote:
Hi Christoph,

Thank you for the response. I think the access within the function masked the real problem we are having.

The issue: matrix multiplication does not behave like other _expression_ templates, e.g. transpose, Map.

Example function (bar.hpp):
#include <Eigen/Dense>
#include <iostream>

template <typename Derived>
void bar(const Eigen::MatrixBase<Derived>& a) {
  std::cout << "a(0): " << a(0) << std::endl;

Example that works:
#include "bar.hpp"

int main() {
  Eigen::MatrixXd u(1,1);
  u << 1;
  Eigen::MatrixXd v(1,2);
  v << 1, 2;


  return 0;

Example that does not work, but I expect to work:
#include "bar.hpp"

int main() {
  Eigen::MatrixXd u(1,1);
  u << 1;
  Eigen::MatrixXd v(1,2);
  v << 1, 2;


  return 0;

This results in:
> ./a.out
Assertion failed: (this->rows() == 1 && this->cols() == 1), function coeff, file /Users/daniel/dev/stan/lib/eigen_3.2.2/Eigen/src/Core/ProductBase.h, line 150.
a(0): Abort trap: 6

I am not expecting this assertion failure. With EIGEN2_SUPPORT defined, this assertion goes away.

Question: did we do something incorrectly with the definition of the function bar?

Thanks again.


On Fri, Mar 13, 2015 at 9:33 AM, Christoph Hertzberg <chtz@xxxxxxxxxxxxxxxxxxxxxxxx> wrote:
Am 12.03.2015 um 21:44 schrieb Daniel Lee:
It seems to work fine for transpose, for Map, for MatrixXd, but
here's a minimal example of the problem we're running into with

Accessing products coefficient-wise is generally not a good idea. If you really want to do that, consider calling foo(u.lazyProduct(v),0,0);
If you want to access multiple coefficients from a inside foo, passing via (const Ref<const MatrixXd>&) is probably a better idea.

If I change the #ifdef to an #ifndef, everything works as expected.
Are we somehow supposed to be setting the EIGEN2_SUPPORT property
ourselves?  If I do that in the compilation, it works as expected, but
I get a deprecation warning:

Yes, you can do that, and you can disable the deprecation warning by also defining EIGEN_NO_EIGEN2_DEPRECATED_WARNING.
But as the warning says, this will not be possible with Eigen 3.3 anymore.
See this and the pages linked from there:


Dipl.-Inf., Dipl.-Math. Christoph Hertzberg
Cartesium 0.049
Universität Bremen
Enrique-Schmidt-Straße 5
28359 Bremen

Tel: +49 (421) 218-64252

Mail converted by MHonArc 2.6.19+