我构造了一个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)
w
和v
证明是复数,并且虚部不可忽略。我也尝试
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/