[eigen] eigen3 SelfAdjointEigenSolver<Matrix3f> still "buggy" |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
We've started adopting Eigen3 in ROS (http://www.ros.org/wiki/eigen3), and so far a thumbs up to the developers for
doing a great job keeping most of the API intact! We documented some of the minor changes that we had to do to our code
at the URL mentioned above, but all in all it was a walk in the park to switch one of our larger code libraries (PCL -
http://www.ros.org/wiki/pcl) to Eigen3 today.
One of the Eigen2 problems however still remains: the usage of SelfAdjointEigenSolver for Matrix3f matrices still gives
a different ("incorrect") solution than for Matrix3d. This was already discussed on this mailing list, and the patch
that we adopted in ROS for Eigen2 was:
(http://bitbucket.org/eigen/eigen/issue/149/selfadjointeigensolver-matrix3f-vs)
1 --- Eigen/src/QR/Tridiagonalization.h 2010-07-22 14:45:32.000000000 -0700
2 +++ Eigen/src/QR/Tridiagonalization.h 2010-07-22 14:46:26.000000000 -0700
3 @@ -391,7 +391,7 @@
4 {
5 diag[0] = ei_real(mat(0,0));
6 RealScalar v1norm2 = ei_abs2(mat(0,2));
7 - if (ei_isMuchSmallerThan(v1norm2, RealScalar(1)))
8 + if (v1norm2==RealScalar(0))
9 {
10 diag[1] = ei_real(mat(1,1));
11 diag[2] = ei_real(mat(2,2));
(https://code.ros.org/svn/ros-pkg/stacks/geometry/trunk/eigen/matrix.patch)
This allowed us to perform the eigen decomposition and get the same values without much precision loss, while keeping
everything else as floats.
In Eigen3 however, the structure of QR changed dramatically, and the 3.0-beta1.tar.bz2 snapshot has not fixed this
issue, meaning that:
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> ei_symm_d;
and
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> ei_symm_f;
would give different values on compute (matrix_{f,d}), where matrix_f = matrix_d (minus the type).
Is there a patch that we can apply against Eigen3 beta1 that would solve this issue?
Thank you in advance.
PS. One of the reasons why we'd like to stick to SelfAdjointEigenSolver<Matrix3f> is the speed. We wrote a few tests in
ROS (under http://www.ros.org/wiki/eigen_tests) for testing the performance of different eigenvector estimation methods
in Eigen. Here are some results on an i7 laptop:
[3double] 0.212725 seconds.
[3float] 0.104199 seconds.
[4double] 0.3162 seconds.
[4float] 0.21743 seconds.
[svd_3double] 0.451361 seconds.
[svd_3float] 0.339349 seconds.
[svd_4double] 0.534939 seconds.
[svd_4float] 0.43122 seconds.
where 3double = Matrix3d, 3float = Matrix3f, 4{double,float} = 4x4 matrix with added 0s for padding (we thought that
keeping the matrix SSE aligned would result in some speedups, but it didn't), and svd_XX = Eigen::SVD<XX>. Overall, the
good old Matrix3f seems to be the fastest.
Cheers,
Radu.
--
| Radu Bogdan Rusu | http://rbrusu.com/