如何用scipy或lapack有效地获得特征向量分解?

时间:2012-07-12 01:06:36

标签: numpy fortran scipy lapack

我想找到一个密集复杂矩阵A

的特征向量分解
A = V.diag(lambda).V^-1

我只需要少量的特征向量来根据我的需要精确地再现矩阵,但是我需要对特征值执行一些非平凡的滤波来确定要包含哪些特征向量。对于我的问题,使用奇异值分解是不合适的,因为特征值/特征向量是我想要使用的物理上有意义的结果。

我正在使用scipy.linalg.eig,它只是lapack ZGEEV例程的一个方便的包装器。在数学上,V^-1应该可以从左特征向量的适当缩放版本获得。我希望这比反转V(右特征向量矩阵)更有效,更稳定

然而,当我比较这两种方法时,似乎在分解矩阵中使用两个左特征向量比使用反向右特征向量精确得多。据推测这是某种舍入或截断错误。我宁愿不反转右特征向量的矩阵,因为它可能非常大(大约1000s),我需要多次重复这个操作。

是否有一些例程可用于scipy(或lapack或其他一些我可以自己包装的例程),它可以有效而准确地进行分解?

2 个答案:

答案 0 :(得分:1)

我现在已经意识到可以从左侧特征向量V^-1获取U,但诀窍是将U的元素标准化为{{1}的相应元素}}。我正在将V的列标准化为自己,这是不正确的,但足够接近它看起来几乎正确。

所以我说你可以从U获得V^-1,这在我的实施中只是一个错误。

答案 1 :(得分:0)

如果我理解正确,你想通过执行乘法来重新获得(逼近)A,但是例程只返回V本身,并且你不想要反转V.

然而,该例程还返回左特征向量U的矩阵,并且可以(如您在我的原始答案的注释中所述)从U获得V的倒数,如下所示:

如果我们评估矩阵U * A * V的 ij 元素,那么它必须等于

U_i * lambda_j * V_j

U_i * lambda_i * V_j

其中U_i是U的 i 行,V_j是V的 j 列(注意,像zgeev这样的lapack例程将行向量作为Fortran返回列向量)。

因此,矩阵U * V是对角线,因此,正如您在自己的答案中所说,您可以通过

来构造V ^ -1
V^-1_i = U_i / (U_i * V_i)

其中U和V ^ -1上的下标表示行,而V上的下标表示列。

相关问题