1

I'm having trouble getting the proper eigenvectors from a covariance matrix. Every other tool I've tried (Hipparchus, numpy, and Wolfram Alpha) all have the same results. Note that the bolded values in the two tables below are the ones that don't match. The values are correct, but the signs are flipped. How can I get Eigen to return values that match the other tools?

Expected (Java Hipparchus, numpy, wolfram alpha):

0.822 -0.5666 0.043 0.0214 -0.01286 0.00185
-0.5082 -0.6991 0.5027 -0.0098 -0.0102 0.0103
-0.2542 -0.4359 -0.8631 -0.0065 -0.0051 -0.02089
0.0233 -0.01 0.0018 -0.882 0.47043 0.00655
-0.000089 -0.0023 0.0228 0.102117 0.20486 -0.97318
0.00802 0.0134 0.00495 -0.4593 -0.85813 -0.2287

Received (Eigen C++):

0.822 -0.5666 0.043 0.0214 -0.01286 0.00185
-0.5082 -0.6991 0.5027 -0.0098 -0.0102 0.0103
0.254237 0.435874 0.86306 0.006458 0.005145 0.02089
-0.023292 0.010035 0.001800 0.882024 -0.470473 -0.006552
-0.000089 -0.0023 -0.022781 -0.102117 -0.204863 0.97318
0.00802 0.0134 0.00495 -0.4593 -0.85813 -0.2287
#include <Eigen/Dense>
#include <iostream>
...
Eigen::Matrix<double, 6, 6> covariance_matrix;
covariance_matrix <<
    11918156.569, -2503013.667, -132100.597, 294232.999, -89836.267, 13818.007,
    -2503013.667, 9953136.379, -660701.613, -85984.752, 177042.329, -10946.126,
    -132100.597, -660701.613, 7553635.065, 10310.484, -20116.259, 174844.429,
    294232.999, -85984.752, 10310.484, 36006.817, -10978.320, -41.400,
    -89836.267, 177042.329, -20116.259, -10978.320, 20835.413, -1528.193,
    13818.007, -10946.126, 174844.429, -41.400, -1528.193, 22188.775;

Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, 6, 6>> eigen_solver(covariance_matrix);
Eigen::Vector<double, 6> eigenvalues = eigen_solver.eigenvalues().reverse(); // values are OK
Eigen::Matrix<double, 6, 6> eigenvectors = eigen_solver.eigenvectors().transpose().colwise().reverse();
std::cout << "eigenvectors:\n" << eigenvectors.matrix() << "\n";
J'e
  • 3,014
  • 4
  • 31
  • 55
  • You provided `covariance_matrix` but then perform the eigensolution on `fme`. I assume you did something in between. – Matt Jul 21 '22 at 18:28
  • that was a typo. they are the same thing. I fixed it. – J'e Jul 21 '22 at 18:30
  • 2
    The sign is arbitrary. When I try to reproduce it with numpy, I get an entirely different set of signs. See for example here for a similar question: https://stackoverflow.com/questions/17998228/sign-of-eigenvectors-change-depending-on-specification-of-the-symmetric-argument – Homer512 Jul 21 '22 at 19:59
  • Your numpy, wolfram, etc table doesn't match what I get when I use those same tools. Your Eigen table does match (as a transposed scalar multiple) of numpy.linalg.eigh, matlab, wolfram and numpy.linalg.eig. – Matt Jul 25 '22 at 14:13

0 Answers0