python : 检查是否可对角化矩阵

python : check if diagonalisable matrix

我想用 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 中的那些是真实的时是否正常? 有没有办法检查这个数组是否可对角化?

非常感谢

您可以使用 SymPy。它有一个函数 is_diagonalizable.

它检查矩阵是否可对角化。

如果 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 是对称的。

可对角化矩阵在 C^nxn 中是稠密的。这对于浮点计算意味着舍入误差使矩阵可对角化——eig(A) 的结果是 eig(Ap),其中 |A - Ap| <= floating point error 和 Ap 是可对角化的。计算特征值的标准数值算法将给出这样的结果。

实矩阵的特征值可以是复数,例如[1 -2; 1 1].

如果使用精确算法,可以完全可靠地检测不可对角化的矩阵;在浮点数中,您也许可以将 "close" 与不可对角化矩阵的可对角化矩阵视为不可对角化矩阵(例如,参见 https://dl.acm.org/citation.cfm?id=355912)。

编辑:可以通过计算特征向量矩阵的条件数w, V = np.linalg.eig(A); c = np.linalg.cond(V) 来获得一种接近浮点非对角化性的度量。如果 c 很大,在 1/eps ~ 10**16 附近,矩阵在数值上接近于不可对角化。