我构造了一个100 * 100的矩阵k,并希望使用numpy.linalg.eig将其对角线化。

k=np.zeros((100,100))
np.fill_diagonal(k,-2)
np.fill_diagonal(k[1:,:-1],1.5)
np.fill_diagonal(k[:-1,1:],0.5)


当我尝试较小的矩阵时,例如

w,v=np.linalg.eig(k[:10,:10])


特征值w和特征向量v是实数。但是当我尝试更大的矩阵或整个完整矩阵时

w,v=np.linalg.eig(k)


wv证明是复数,并且虚部不可忽略。

我也尝试scipy.linalg.eig,它也有类似的问题。

我想采用特征值和特征向量的自然对数。我的模型中没有复数的物理含义。

我怎么只能有独立的实数特征值和特征向量?如果不是,如何通过python将复数特征值和特征向量更改为实数?

最佳答案

@Daniel F和@FTP比我快,请看他们的评论,但是由于我坐在这里的代码,我不妨分享一下:

import numpy as np
from scipy import sparse

def tri_toep_eig(a, b, c, n):
    evals = a + 2*np.sqrt(b*c) * np.cos(np.pi * np.arange(1, n+1) / (n+1))
    evecs = np.sin(np.outer(np.arange(1, n+1) * np.pi / (n+1),
                            np.arange(1, n+1))) \
        * np.sqrt(b/c)**np.arange(n)[:, None]
    return evals, evecs

def tri_toep(a, b, c, n):
    return sparse.dia_matrix((np.outer((b, a, c), np.ones((n,))),
                              (-1, 0, 1)), (n, n))
def check(a, b, c, n):
    evals, evecs = tri_toep_eig(a, b, c, n)
    tt = tri_toep(a, b, c, n)
    for eva, eve in zip(evals, evecs.T):
        assert np.allclose(tt @ eve, eva * eve)

check(-2, 0.5, 1.5, 100)

关于python - 如何获得三对角Toeplitz矩阵的真实特征值和特征向量?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48999970/

10-12 18:26
查看更多