Reputation: 39
So I am using Eigen for C++ in code blocks to calculate eigenvalues for my matrices. The specific part of the code that deals with this is as follows:-
EigenSolver<MatrixXd> b(B,false);
cout<<" Eigen values are: \n "<<b.eigenvalues()<<"\n";
The problem I have been encountering is is that one of the eigenvalues calculated for my matrix B is nowhere close to the actual eigenvalue I found on calculator.vhex.net.
For example, for the matrix
1 0 0 x
0 1 x 0
0 x 1 y
x 0 y 1
where x = -1/sqrt(2) and y = -0.5 , the eigenvalues are 0, 0.5, 1.5 and 2.
However, my code calculates them to be -4.25e-016 , 0.5, 1.5 and 2.
I also tried this for a 5x5 matrix which should have had an eigenvalue 4e-06 , but the code calculated it as 1.4413e-017 .
What could be the reason(s) for this? Are they approximations? My guess is memory issues and that a double type value of square root of 2 will not exactly equal to the square root of 2, but I am not sure about this.
What could be a possible fix for this?
Upvotes: 2
Views: 3162
Reputation: 7820
I guess it depends on which eigenvalue decomposition technique is being used. More information you can find here: https://eigen.tuxfamily.org/dox/group__Eigenvalues__Module.html
This is how it is done for selfadjoint matrices
std::vector<std::tuple<float, Eigen::VectorXf>> eigen_vectors_and_values;
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eigensolver(covariance_matrix);
if (eigensolver.info() != Eigen::Success) {
return;
}
Eigen::VectorXf eigen_values = eigensolver.eigenvalues();
Eigen::MatrixXf eigen_vectors = eigensolver.eigenvectors();
std::cout<< "eigen_vectors" << eigen_vectors << std::endl;
std::cout<< "eigen_values" << eigen_values << std::endl;
For general matrices
Eigen::EigenSolver<Eigen::MatrixXf> eigensolver;
eigensolver.compute(covariance_matrix);
Eigen::VectorXf eigen_values = eigensolver.eigenvalues().real();
Eigen::MatrixXf eigen_vectors = eigensolver.eigenvectors().real();
std::cout<< "eigen_vectors" << eigen_vectors.real() << std::endl;
std::cout<< "eigen_values" << eigen_values.real() << std::endl;
Here covariance_matrix is the matrix in which eigenvalues and eigenvectors are to be calculated.
Upvotes: 0
Reputation: 18827
Additionally to what @drglove said, for symmetric (or selfadjoint) Eigenvalue problems you should use the SelfAdjointEigenSolver
:
SelfAdjointEigenSolver<MatrixXd> b(B,EigenvaluesOnly);
This gives of course still only a numerical solution, so you will still get solutions with a limited precision.
Upvotes: 0
Reputation: 658
Finding eigenvalues can be difficult when the matrix is near singular, which is indicated with a 0 eigenvalue. You should not expect an exact eigenvalue of 0 ever from a numerical solution, since it will only be good up to some numerical approximation which starts failing near that point.
Upvotes: 6