From: Gael Guennebaud <gael.gu...@gmail.com>
Date: March 13, 2015 at 4:57:23 PM EDT
To: eigen <ei...@lists.tuxfamily.org>
Subject: Re: [eigen] help using foo(const MatrixBase<T>&) with (u * v)
Reply-To: ei...@lists.tuxfamily.org
Hi,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:bar((u*v).transpose())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:bar(u.lazyProduct(v))lazyProduct returns a "true" expression template.if you are going to access to all coefficients then rather call bar like this:bar((u*v).eval()).gaelOn Fri, Mar 13, 2015 at 3:57 PM, Daniel Lee <bea...@alum.mit.edu> 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.I am following instructions here: http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.htmlExample 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;
bar((u*v).transpose());
bar((u*v).transpose().transpose());
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;
bar(u*v);
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: 6I 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.DanielOn Fri, Mar 13, 2015 at 9:33 AM, Christoph Hertzberg <ch...@informatik.uni-bremen.de> 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
products:
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:
http://eigen.tuxfamily.org/dox/Eigen2ToEigen3.html
Christoph
--
----------------------------------------------
Dipl.-Inf., Dipl.-Math. Christoph Hertzberg
Cartesium 0.049
Universität Bremen
Enrique-Schmidt-Straße 5
28359 Bremen
Tel: +49 (421) 218-64252
----------------------------------------------
Here's a simple example:#include <Eigen/Dense>
#include <iostream>
template <typename Derived>
void bar(const Eigen::MatrixBase<Derived>& a) {
std::cout << "a(0): " << a(0) << std::endl;
}
On Thursday, August 18, 2016 at 7:31:46 AM UTC-4, Daniel Lee wrote:Here's a simple example:#include <Eigen/Dense>
#include <iostream>
template <typename Derived>
void bar(const Eigen::MatrixBase<Derived>& a) {
std::cout << "a(0): " << a(0) << std::endl;
}
This is not the recommended way to access elements of an Eigen object anyway.
If you change it to
std::cout << "a(0): " << a.coeff(0) << std::endl;
then it does not segfault.
Ben
--
You received this message because you are subscribed to the Google Groups "stan development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to stan-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
On Thu, Aug 18, 2016 at 10:29 AM, Ben Goodrich <goodri...@gmail.com> wrote:On Thursday, August 18, 2016 at 7:31:46 AM UTC-4, Daniel Lee wrote:Here's a simple example:#include <Eigen/Dense>
#include <iostream>
template <typename Derived>
void bar(const Eigen::MatrixBase<Derived>& a) {
std::cout << "a(0): " << a(0) << std::endl;
}
This is not the recommended way to access elements of an Eigen object anyway.Really? Where do you find that sort of doc? I can't find it on Eigen's page.
I didn't see anywhere where they recommended coeff() for element access. Did I miss it somewhere?