C ++的特征值计算错误的特征值
Eigen for c++ calculating wrong eigenvalue
所以我在代码块中使用 C++ 的 Eigen 来计算我的矩阵的特征值。具体处理这个的部分代码如下:-
EigenSolver<MatrixXd> b(B,false);
cout<<" Eigen values are: \n "<<b.eigenvalues()<<"\n";
我遇到的问题是为我的矩阵 B 计算的特征值之一与我在 calculator.vhex.net 上找到的实际特征值相去甚远。
例如,对于矩阵
1 0 0 x
0 1 x 0
0 x 1 y
x 0 y 1
其中 x = -1/sqrt(2) 和 y = -0.5 ,特征值为 0、0.5、1.5 和 2。
但是,我的代码将它们计算为 -4.25e-016、0.5、1.5 和 2。
我还对一个本应具有特征值 4e-06 的 5x5 矩阵进行了尝试,但代码将其计算为 1.4413e-017 。
这可能是什么原因?它们是近似值吗?
我的猜测是内存问题,2 的平方根的 double 类型值不会完全等于 2 的平方根,但我不确定这一点。
有什么可能的解决方法?
当矩阵接近奇异时,查找特征值可能会很困难,这用 0 特征值表示。你不应该期望从数值解中得到一个精确的特征值 0,因为它只会在一些数值近似值附近开始失败时才有用。
除了@drglove 所说的,对于对称(或自伴)特征值问题,您应该使用 SelfAdjointEigenSolver
:
SelfAdjointEigenSolver<MatrixXd> b(B,EigenvaluesOnly);
这当然仍然只是一个数值解,因此您仍然会得到精度有限的解。
我想这取决于所使用的特征值分解技术。您可以在此处找到更多信息:https://eigen.tuxfamily.org/dox/group__Eigenvalues__Module.html
的处理方式
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;
对于一般矩阵
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;
这里covariance_matrix是要计算特征值和特征向量的矩阵
所以我在代码块中使用 C++ 的 Eigen 来计算我的矩阵的特征值。具体处理这个的部分代码如下:-
EigenSolver<MatrixXd> b(B,false);
cout<<" Eigen values are: \n "<<b.eigenvalues()<<"\n";
我遇到的问题是为我的矩阵 B 计算的特征值之一与我在 calculator.vhex.net 上找到的实际特征值相去甚远。
例如,对于矩阵
1 0 0 x
0 1 x 0
0 x 1 y
x 0 y 1
其中 x = -1/sqrt(2) 和 y = -0.5 ,特征值为 0、0.5、1.5 和 2。
但是,我的代码将它们计算为 -4.25e-016、0.5、1.5 和 2。
我还对一个本应具有特征值 4e-06 的 5x5 矩阵进行了尝试,但代码将其计算为 1.4413e-017 。
这可能是什么原因?它们是近似值吗? 我的猜测是内存问题,2 的平方根的 double 类型值不会完全等于 2 的平方根,但我不确定这一点。
有什么可能的解决方法?
当矩阵接近奇异时,查找特征值可能会很困难,这用 0 特征值表示。你不应该期望从数值解中得到一个精确的特征值 0,因为它只会在一些数值近似值附近开始失败时才有用。
除了@drglove 所说的,对于对称(或自伴)特征值问题,您应该使用 SelfAdjointEigenSolver
:
SelfAdjointEigenSolver<MatrixXd> b(B,EigenvaluesOnly);
这当然仍然只是一个数值解,因此您仍然会得到精度有限的解。
我想这取决于所使用的特征值分解技术。您可以在此处找到更多信息:https://eigen.tuxfamily.org/dox/group__Eigenvalues__Module.html
的处理方式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;
对于一般矩阵
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;
这里covariance_matrix是要计算特征值和特征向量的矩阵