This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Unstable results when inverting a Matrix3d

Tags: None
(comma "," separated)
Achkan
Registered Member
Posts
2
Karma
0
Hi,

I'm not sure if it's a bug or if I'm doing something wrong. I have a member function

const Eigen::Matrix3d & do_stuff()
{
return _some_member_matrix;
}

Eigen::Matrix3d M=do_stuff();
//strange behavior
std::cout<<M.inverse()<<std::endl; //the output is correct
M=M.inverse();
std::cout<<M<<std::endl; //WRONG result.
//... stuff ...

I have notices that declaring the matrix M as Eigen::MatrixXd fixes this problem, but I don't understand why, and I don't know if this is normal. Thanks in advance!
Tal
Registered Member
Posts
30
Karma
0
Achkan wrote:Hi,

I'm not sure if it's a bug or if I'm doing something wrong. I have a member function

const Eigen::Matrix3d & do_stuff()
{
return _some_member_matrix;
}

Eigen::Matrix3d M=do_stuff();
//strange behavior
std::cout<<M.inverse()<<std::endl; //the output is correct
M=M.inverse();
std::cout<<M<<std::endl; //WRONG result.
//... stuff ...

This is called aliasing issue.
In short (and not exact) words, Eigen trust that you wouldn't assign an expression to something(e.g. Matrix) that is depend on itself.
Because you failed to complete this requirement, Eigen might do bad things in return.

This pitfall is there, because it opens up a HUGE optimization opportunity!

You should read this page for a full explanation:
http://eigen.tuxfamily.org/dox/group__T ... asing.html

For your needs, you COULD do:
Code: Select all
M=M.inverse().eval();

This eval() member function convert a temporal template expression to a matrix storage.
But this is very bad for performance! I was just showing a point here.

From your code style, I think that you assign M inverse result to itself in order to use less resources, otherwise it wouldn't made sense to invert it twice. (probably it was just a test only code, but I'm trying show here a point)
This is not right in Eigen, since it use more in this case, if you still don't understand why, you should read the page I referred above,

What you SHOULD do:
Code: Select all
/* Matrix3d */ M_inv=M.inverse();// Either assign to another matrix or create a new one
// No need to inverse again in order to get M

This is the most ideal code you can get. (I think)

Achkan wrote:I have notices that declaring the matrix M as Eigen::MatrixXd fixes this problem, but I don't understand why, and I don't know if this is normal. Thanks in advance!

I said before that when you do bad aliasing, Eigen might do bad things in return. It's Eigen internal why it worked for you, but it was just "luck".


Achkan
Registered Member
Posts
2
Karma
0
Thanks a lot for that explanation. I think the documentation should warn users about that sooner, in "getting started with eigen" for example.
Tal
Registered Member
Posts
30
Karma
0
Achkan wrote:I think the documentation should warn users about that sooner, in "getting started with eigen" for example.

Couldn't agree more...




Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], q.ignora, watchstar