如果我们在 C++ 代码中为两个不良条件矩阵调用 LAPACKDGGEV
或例程,我们会得到与 MATLAB命令DGGEVX
相同的特征值和向量,其算法如下:?eig
'qz'
eig(a,b,'qz')
MATLAB 的特征向量是否有可能与 LAPACKDGGEV
或不同DGGEVX
?
如果我们在 C++ 代码中为两个不良条件矩阵调用 LAPACKDGGEV
或例程,我们会得到与 MATLAB命令DGGEVX
相同的特征值和向量,其算法如下:?eig
'qz'
eig(a,b,'qz')
MATLAB 的特征向量是否有可能与 LAPACKDGGEV
或不同DGGEVX
?
需要注意的几点:
根据定义A·v = λ·v
,特征向量不是唯一的。你可以乘以任何常数,仍然得到另一个有效的特征向量。
MATLAB 中的约定是,对于eig(A)
,特征向量被缩放,使得每个的范数是 1.0,对于eig(A,B)
,特征向量没有被归一化(参见这里的例子)。这是文档中的相关部分:
V
: 右特征向量,以方阵形式返回,其列是该对的右特征向量A
或广义右特征向量(A,B)
。的形式和规范化V
取决于输入参数的组合:
[V,D] = eig(A)
返回矩阵V
,其列是这样的右特征A
向量A*V = V*D
。中的特征向量V
被归一化,使得每个的 2 范数为 1。
[V,D] = eig(A,'nobalance')
还返回矩阵V
。但是,每个特征向量的 2 范数不一定是 1。
[V,D] = eig(A,B)
并作为矩阵[V,D] = eig(A,B,algorithm)
返回V
,其列是满足 的广义右特征向量A*V = B*V*D
。每个特征向量的 2 范数不一定是 1。在这种情况下,包含沿主对角线D
的对 的广义特征值。(A,B)
如果
A
是对称的并且B
是对称正定的,则对 in 的特征向量V
进行归一化,使得每个的 2 范数为 1。
此外,特征值未 排序。您只能保证 的列是V
中特征值的对应右特征向量D
。那不一样svd
。
事实上,复数没有全序。MATLAB 中的约定是该sort
函数首先按幅度(即 )对复元素进行排序,然后如果幅度相等,则按区间abs(x)
上的相位角(即 )。[-pi,pi]
angle(x)
考虑到上述情况,在求解广义特征值问题时,您应该通过在 LAPACK 中使用 DGGEV 例程获得与 MATLAB 相似的结果。
找到这个问题的答案的最好方法是进行实验:
我们使用 MATLAB R2013b 使用eig
类似的命令计算了两个不良条件矩阵的特征值和向量eig(a,b,'qz')
。病态矩阵的大小为 342x342。
根据以下链接上的解释,MATLAB R2009a 实现了 LAPACK DGGEV 以执行以下操作eig(a,b,'qz')
:
因此,我们在 C++ 代码中使用 LAPACK E实现了来自 LAPACK 的 DGGEV(以及 DGGEVX)例程,LAPACK E是由 INTEL-MKL 团队开发的 LAPACK 的“C”语言包装器。
结论是我们得到了与 MATLAB 完全相同的特征值和向量eig(a,b,'qz')
。
请注意,如果您使用 DGGEVX(DGGEV 的专家版),您应该使用 for BLANC 参数关闭平衡,以获得与 MATLAB算法'N'
完全相同的特征向量。'qz'
我们还通过检查特征值和向量是否满足来检查它们的正确性,A*V-B*V*D=0
结论是特征值和向量是正确的,因为残差足够接近于零。