We (Bob, myself, and I believe @jpritikin and perhaps a handful of others) evaluated a long time ago whether we could switch over to using Eigen::DenseBase
. Although the doc makes it seem like it’s a drop-in replacement for Eigen::Matrix
, unfortunately it isn’t. If you start implementing, you’ll find that numerical results don’t line up. I believe it was a design decision in Eigen for certain things to behave differently (there should be a post on Eigen’s mailing list from me with a couple interactions), and so in order to do this correctly, we’d have to carry around an implementation of both Eigen::DenseBase
and Eigen::Matrix
.
Correction… we evaluated Eigen::MatrixBase
, not Eigen::DenseBase
. At the bottom, I’ve attached an email that I sent out (which I can’t find on the Eigen mailing list); I think I received a comment back at some point.
But… if I’m to guess at the purpose, do we actually need these to be in Eigen data structures for linear algebra? Or are we just looking to access slices? If it’s the later, then we could do whatever would make the implementation work… pointers and iterators do seem to be the natural way to do this.
From: Daniel Lee
Date: March 12, 2015 at 4:44:36 PM EDT
To: eigen@lists.tuxfamily.org
Subject: help using foo(const MatrixBase&) with (u * v)
We’re trying to follow the advice on this page:
http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html
and running into trouble passing the expression template (u * v)
to a function declared as suggested above.
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
products:
#include <Eigen/Dense>
template <typename Derived>
double foo(const Eigen::MatrixBase<Derived>& a, int m, int n) {
return a(m,n);
}
int main() {
Eigen::MatrixXd u(2,2);
u << 1, 2, 3, 4;
Eigen::MatrixXd v(2,3);
v << 1, 2, 3, 4, 5, 6;
foo(u*v, 0, 0);
return 0;
}
~/temp2$ clang++ -I ~/stan/lib/eigen_3.2.2 eigen-test.cpp
~/temp2$ ./a.out
Assertion failed: (this->rows() == 1 && this->cols() == 1), function coeff, file /Users/carp/stan/lib/eigen_3.2.2/Eigen/src/Core/ProductBase.h, line 141.
Abort trap: 6
~/temp2$ clang++ --version
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
Here’s the relevant part of Eigen/src/Core/ProductBase.h:
typename Base::CoeffReturnType coeff(Index row, Index col) const
{
#ifdef EIGEN2_SUPPORT
return lhs().row(row).cwiseProduct(rhs().col(col).transpose()).sum();
#else
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
eigen_assert(this->rows() == 1 && this->cols() == 1); // *** LINE 141 ***
Matrix<Scalar,1,1> result = *this;
return result.coeff(row,col);
#endif
}
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:
~/temp2$ clang++ -I ~/stan/lib/eigen_3.2.2 -DEIGEN2_SUPPORT eigen-test.cpp
In file included from eigen-test.cpp:1:
In file included from /Users/carp/stan/lib/eigen_3.2.2/Eigen/Dense:1:
In file included from /Users/carp/stan/lib/eigen_3.2.2/Eigen/Core:373:
/Users/carp/stan/lib/eigen_3.2.2/Eigen/Eigen2Support:20:2: warning: "Eigen2 support is
deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define
EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)" [-W#warnings]
#warning "Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3...
^
1 warning generated.
~/temp2$ ./a.out
~/temp2$
Daniel