这意味着它也应该适用于Hermitian(复杂的,而不是纯粹的)矩阵。是这样的吗?
一个最小的例子表明它实际上不能用Hermitian矩阵天真地工作。是否有人需要知道的技巧或描述中的错误?
我的最小例子使用自旋3/2矩阵Sx(实对称)和Sy(复Hermitian),其特征值知道为-1.5,-0.5,0.5,1.5。
真实对称情况的结果很好,但在复杂的情况下,它会产生NaN。
#include <iostream>
#include <complex>
#include <Eigen/Core>
#include <Eigen/IterativeLinearSolvers>
int main(int args, char **argv){
Eigen::VectorXcd b=Eigen::VectorXcd::Ones(4);
Eigen::VectorXcd x;
std::complex<double> i_unit(0,1);
//Hermitian matrix:
Eigen::MatrixXcd A(4,4);
A<<0,-i_unit*sqrt(3.)/2., 0 ,0, \
i_unit*sqrt(3.)/2., 0 ,-i_unit, 0,\
0,i_unit,0,-i_unit*sqrt(3.)/2.,\
0,0,i_unit*sqrt(3.)/2.,0;
//Real symmetric matrix:
Eigen::MatrixXcd B(4,4);
B<<0,sqrt(3.)/2., 0 ,0, \
sqrt(3.)/2., 0 ,1, 0,\
0,1,0,sqrt(3.)/2.,\
0,0,sqrt(3.)/2.,0;
Eigen::ConjugateGradient< Eigen::MatrixXcd, Eigen::Lower|Eigen::Upper> cg;
cg.compute(A);
x = cg.solve(b);
std::cout<<"Hermitian matrix:"<<std::endl;
std::cout<<"A: "<<std::endl<<A<<std::endl;
std::cout<<"b: "<<std::endl<<b<<std::endl;
std::cout<<"x: "<<std::endl<<x<<std::endl;
std::cout<<"(b-A*x).norm(): "<<(b-A*x).norm()<<std::endl;
std::cout<<"cg.error(): "<<cg.error()<<std::endl;
std::cout<<std::endl;
cg.compute(B);
x = cg.solve(b);
std::cout<<"Real symmetric matrix:"<<std::endl;
std::cout<<"B: "<<std::endl<<B<<std::endl;
std::cout<<"b: "<<std::endl<<b<<std::endl;
std::cout<<"x: "<<std::endl<<x<<std::endl;
std::cout<<"(b-B*x).norm(): "<<(b-B*x).norm()<<std::endl;
std::cout<<"cg.error(): "<<cg.error()<<std::endl;
std::cout<<std::endl;
return 0;
}
答案 0 :(得分:0)
Hermitian是不够的,它也需要正定,这不是你的情况,因为你的矩阵有正负特征值。无论如何,CG设计用于处理非常大的稀疏矩阵,对于4x4矩阵,更好地使用密集分解。在您的情况下,LDLT
会很好。