我想用Python对矩阵进行对角化,这是我的脚本:
import scipy.linalg as lg
vp = lg.eig(A) # eigen values and vectors
D = N.diag(vp[0]) # diagonalisation of A from its eigen values
P=vp[1] # such as A = P.D.P(-1)
Pm1=lg.inv(P)
然而我怀疑A不是对角线的,但是这并不妨碍Python毫无困难地计算D,P和P(-1)......更重要的是,D中的系数是复数,是A中的人是真的吗? 有没有办法检查这个数组是否可以对角线?
非常感谢提前
答案 0 :(得分:3)
可对角化矩阵在C ^ nxn中是密集的。这对于浮点计算意味着舍入误差使得矩阵可对角化 - eig(A)
的结果是eig(Ap)
,其中|A - Ap| <= floating point error
和Ap是可对角化的。计算特征值的标准数值算法将给出这样的结果。
真实矩阵的特征值可能很复杂,例如[1 -2; 1 1]
。
如果使用精确算术,则可以完全可靠地检测不可对角化的矩阵;在浮点数中,您可以考虑对角化矩阵,即“关闭”#34;不可对角化的那些是不可对角化的(参见例如https://dl.acm.org/citation.cfm?id=355912)。
编辑:通过计算特征向量矩阵的条件数w, V = np.linalg.eig(A); c = np.linalg.cond(V)
,可以获得一个接近浮点非对角化的度量。如果c
很大,大约1/eps ~ 10**16
,则矩阵在数值上接近不可对角化。
答案 1 :(得分:2)
您可以使用SymPy。它有一个函数is_diagonalizable
。
检查矩阵是否是对角线的。
答案 2 :(得分:0)
如果A
不可对角化,则P
中的向量将线性相关。但是,由于数值误差,它们可能非常接近线性相关。
例如,考虑
P = array([[1, 0],[1, 0.001]])
让
Pm1 = inv(P)
然后P * Pm1 - eye(2)
将远离零
[[ 0. 0.]
[-1000. 0.]]
计算逆时,请始终查看矩阵的条件数。例如cond(P) = 2000.5
这是一个非常大的数字。
同样对于某些矩阵,eig()
由于数值误差而再次输出可能与特征值的真实列表相距甚远。
对于复杂的特征值,回想一下真实矩阵可能具有复杂的特征值,尽管它们将是复共轭对。由于实数场不是代数闭合的,除非矩阵A
是对称的,否则你不能指望特征值总是真实的。