【问题标题】:How to efficiently get eigenvector decomposition with scipy or lapack?如何使用 scipy 或 lapack 有效地进行特征向量分解?
【发布时间】:2012-07-12 01:06:36
【问题描述】:

我想找一个密集复矩阵的特征向量分解A

A = V.diag(lambda).V^-1

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

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

但是,当我比较这两种方法时,似乎在分解矩阵中同时使用左特征向量比使用反转右特征向量准确得多。大概这是某种舍入或截断错误。我不希望反转右特征向量的矩阵,因为它可能非常大(大约 1000 秒),我需要多次重复此操作。

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

【问题讨论】:

    标签: numpy fortran scipy lapack


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      如果我理解正确,您想通过执行乘法来重新获得(近似值)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 上的下标表示列。

      【讨论】:

      • 根据数值配方的第 11 章,在最一般的情况下,每个右特征向量都与所有左特征向量正交,除了具有相同特征值的那个。这意味着 U 和 V 的乘积必须是对角矩阵,并且如果它们被适当地缩放,它们应该是彼此的逆矩阵。
      • @Bago - 这意味着我应该能够从 U 获得 V^-1,这就是我想要做的。从数值上看,我看到这产生的结果几乎是正确的,但对于我的需要来说不够准确。
      猜你喜欢
      • 2018-03-03
      • 1970-01-01
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多