numpy.eig得到的特征向量不正交

1 投票
2 回答
4847 浏览
提问于 2025-04-18 18:05

我的问题是这样的:我使用scipy.linalg.eig来获取特征向量和特征值时,发现我的所有特征值的重数都是1。但是,当我运行下面的代码时,却没有确认特征向量是正交的,按理说在这种情况下应该是正交的。请问这是什么原因呢?或者我该如何解决这个问题?

import scipy as SP
import numpy as NP
from scipy import linalg
from numpy import linspace,asscalar,argsort
import cmath
import time

matA=SP.array([[-0.0001, 0., 0., 0.00001, 0., 0., 0.00002, 0.],[0., -0.0002, 0., 
  0., 0., 0., 0., 0.],[0., 0., -0.00015, 0., 0., -9.*10**-6, 
  0., -0.00005],[0.00001, 0., 0., -0.0001, 0., 0.00001, 1.*10**-6, 
  0.],[0., 0., 0., -5.*10**-6, -0.0001, 0., 0., 0.],[0., -9.*10**-6, 
  0., 0.00001, 0., -0.0002, 0., 0.00005],[0., 0., 0., 0.00002, 0., 
  0., -0.0001, 0.],[0., 0.00004, 0., 0., 0., 0.00005, 0., -0.00015]])

matB=SP.array([[0., 0., 0., 0., 0., 0., 0., 0.],[0., 0., 1.5*10**-10, 0., 0., 0., 
  0., 0.],[0., -1.5*10**-10, 0., 0., 0., 0., 0., 0.],[0., 0., 0., 0.,
   0., 0., 0., 0.],[0., 0., 0., 0., 0., 3.*10**-10, 0., 0.],[0., 0., 
  0., 0., -3.*10**-10, 0., 2.*10**-10, 0.],[0., 0., 0., 0., 
  0., -2.*10**-10, 0., 0.],[0., 0., 0., 0., 0., 0., 0., 0.]])

matdim=len(matB[0])

#coefficient matrix for original ODE
def matM(x):
    return matA+(x**2)*matB

#define sorted eigensystem function
def eigsys(x):
    evs,EVS=linalg.eig(matM(x),check_finite=False)
    absevs=abs(evs)
    idx=argsort(absevs)[::-1]
    evs=evs[idx]
    EVS=EVS[:,idx]
    return (evs,EVS)

#check for orthogonality
eigvecs=SP.transpose(eigsys(60000)[1])
for j in range(8):
    for i in range(8):
        print SP.vdot(eigvecs[i],eigvecs[j])

#show eigenvalues all have multiplicity 1
print eigsys(60000)[0]  

2 个回答

0

很多人提到,虽然不同的特征值不一定能保证特征向量是正交的,但我们有两种特殊类型的矩阵:对称矩阵和厄米矩阵

在这些矩阵中,特征值一定是实数,并且存在一组正交的特征向量(即使特征值不全不同也没关系)。

numpy 中,

numpy.linalg.eig(any_matrix)

可以返回任何矩阵的特征值和特征向量(特征向量可能不是正交的)。

而且我们有内置的功能可以找到对称矩阵和厄米矩阵的正交特征向量

eigen_values, eigen_vectors = numpy.linalg.eigh(symmetric_matrix)

注意numpy.linalg.eigh 只会考虑矩阵的上三角部分或下三角部分来计算特征值(对于这些特殊矩阵,上下三角部分就像镜像一样)。

所以,如果你传入一个既不是对称矩阵也不是厄米矩阵的矩阵来获取正交特征向量,它会构造一个对称矩阵(实际上并没有构造,只是为了帮助理解)并使用这个矩阵的下三角部分来返回特征值和特征向量(这些特征向量是正交的!)。这样得到的结果就会是错误的!

想了解更多细节,请参考:

4

为什么它们应该是正交的呢?你的矩阵

a=matM(60000)

看起来并不是对称的,

abs(a-a.T).max() -> 2.16

而且

abs(a).max() -> 1.08

所以我不一定会期待得到正交的特征向量。是不是有可能函数 matM 或者数据 matAmatB 有问题呢?

撰写回答