简体   繁体   English

C ++的特征值计算错误的特征值

[英]Eigen for c++ calculating wrong eigenvalue

So I am using Eigen for C++ in code blocks to calculate eigenvalues for my matrices. 所以我在代码块中使用Eigen for C ++来计算矩阵的特征值。 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. 我一直遇到的问题是,为我的矩阵B计算的特征值之一与我在Calculator.vhex.net上找到的实际特征值相去甚远。

For example, for the matrix 例如,对于矩阵

1 0 0 x 1 0 0 x

0 1 x 0 0 1 x 0

0 x 1 y 0 x 1年

x 0 y 1 x 0 y 1

where x = -1/sqrt(2) and y = -0.5 , the eigenvalues are 0, 0.5, 1.5 and 2. 其中x = -1 / sqrt(2)和y = -0.5时,特征值分别为0、0.5、1.5和2。

However, my code calculates them to be -4.25e-016 , 0.5, 1.5 and 2. 但是,我的代码将其计算为-4.25e-016,0.5、1.5和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 . 我还对5x5矩阵进行了尝试,该矩阵本应具有特征值4e-06,但是代码将其计算为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. 我的猜测是内存问题,平方根2的双精度类型值将不完全等于2的平方根,但是对此我不确定。

What could be a possible fix for this? 有什么可能的解决办法?

Finding eigenvalues can be difficult when the matrix is near singular, which is indicated with a 0 eigenvalue. 当矩阵接近奇异时(以0特征值表示),很难找到特征值。 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. 您不应该期望从数值解中得出确切的特征值0,因为它只有在达到某个数值近似值(在该点附近开始失效)时才是正确的。

Additionally to what @drglove said, for symmetric (or selfadjoint) Eigenvalue problems you should use the SelfAdjointEigenSolver : 除了@drglove所说的以外,对于对称(或自伴)特征值问题,您应该使用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. 当然,这仍然仅提供了数值解,因此您仍然会获得有限精度的解。

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 您可以在这里找到更多信息: 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. 在这里, covariance_matrix是要在其中计算特征值和特征向量的矩阵。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM