DarthChant
DarthChant

Reputation: 39

Eigen for c++ calculating wrong eigenvalue

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

Answers (3)

GPrathap
GPrathap

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

chtz
chtz

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

drglove
drglove

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

Related Questions