如何让C++ Eigen库特征向量计算结果与Matlab eig输出一致
特征向量差异核心原因
特征向量本身允许乘以任意非零复常数,Matlab为了保证输出的唯一性,会对特征向量做额外的归一化后处理,而Eigen的EigenSolver仅返回满足A*v = λ*v且L2范数为1的特征向量,没有做相位调整步骤,这是二者输出不一致的核心原因。
完全对齐Matlab的实现方案
按如下步骤处理Eigen的输出即可匹配Matlab结果:
- 对齐特征值顺序
首先对计算得到的特征值做排序,确保和Matlab输出顺序一致。Matlab默认排序规则为:复特征值按共轭对分组,每组先返回虚部为正的特征值,再返回虚部为负的,整体按特征值模长从大到小排序。你当前测试用例的顺序已经对齐,若遇到顺序不一致的情况可先做排序匹配。 - 特征向量相位调整
对每一列特征向量(对应一个特征值)做如下处理:
- 遍历该列所有元素,找到模值最大的元素
v_max - 计算缩放因子
scale = conj(v_max) / abs(v_max),其中conj为取复数共轭,abs为取复数模长 - 将整列特征向量乘以
scale,即可将模最大的元素调整为正实数,和Matlab的归一化规则完全一致
- 精度对齐(可选)
如果业务要求浮点数精度完全匹配,保持当前MatrixXd双精度类型即可,同时注意矩阵构造时的输入数值精度和Matlab完全一致。
效果验证
以你给出的测试用例为例:
- Eigen输出的第一列特征向量中,模最大元素为第一个元素
0.349378 + 0.540657i,计算得到scale后整列相乘,第一个元素变为0.6437 + 0i,和Matlab输出第一列第一个元素完全一致 - Eigen输出的第三列特征向量中,模最大元素为第三个元素
-0.594826 -0.663137i,乘以对应scale后第三个元素变为0.8908 + 0i,和Matlab第三列第三个元素完全匹配
内容的提问来源于stack exchange,提问作者Dresult
相关产品推荐
相关产品推荐

