您已经知道了特征值是(0,a,b,c,...,1)
。让我重新命名您的参数,使得特征值为(0,e1,e2,e3,...,1)
。为了找到对应于特征值ej
的特征向量(v0,v1,v2,...,v(n-1))
,您需要解决以下方程组:
v1 = v0*ej
v1*e1 + v2*(1-e1) = v1*ej
v2*e2 + v3*(1-e2) = v2*ej
...
vj*ej + v(j+1)*(1-ej) = vj*ej
...
v(n-1) = v(n-1)*ej
很明显,如果你的所有`ei`都不相同且不等于0或1,则解始终是明确定义的。在处理`ej`时,得到的特征向量的前`j`个分量非零,其余分量为零。这保证了没有特征向量是其他向量的线性组合,因此特征向量矩阵是可逆的。
当一些`ei`是0或1,或者重复时,问题就来了。我无法提供证明,但通过尝试以下代码,似乎只有在两个`ei`相等且不等于1时才需要担心:
>>> def make_mat(values):
... n = len(values) + 2
... main_diag = np.concatenate(([0], values, [1]))
... up_diag = 1 - np.concatenate(([0], values))
... return np.diag(main_diag) + np.diag(up_diag, k=1)
>>> make_mat([4,5,6])
array([[ 0, 1, 0, 0, 0],
[ 0, 4, -3, 0, 0],
[ 0, 0, 5, -4, 0],
[ 0, 0, 0, 6, -5],
[ 0, 0, 0, 0, 1]])
>>> a, b = np.linalg.eig(make_mat([4,5,6]))
>>> a
array([ 0., 4., 5., 6., 1.])
>>> b
array([[ 1. , 0.24253563, -0.18641093, 0.13608276, 0.4472136 ],
[ 0. , 0.9701425 , -0.93205465, 0.81649658, 0.4472136 ],
[ 0. , 0. , 0.31068488, -0.54433105, 0.4472136 ],
[ 0. , 0. , 0. , 0.13608276, 0.4472136 ],
[ 0. , 0. , 0. , 0. , 0.4472136 ]])
现在来看一些测试用例:
>>> a, b = np.linalg.eig(make_mat([1,0,3])) # having a 0 or 1 is OK
>>> b
array([[ 1. , 0.70710678, 0. , 0. , 0. ],
[ 0. , 0.70710678, 0. , 0. , 0. ],
[ 0. , 0. , 1. , 0.31622777, 0.57735027],
[ 0. , 0. , 0. , 0.9486833 , 0.57735027],
[ 0. , 0. , 0. , 0. , 0.57735027]])
>>> a, b = np.linalg.eig(make_mat([1,1,3])) # repeating 1 is OK
>>> b
array([[ 1. , 0.70710678, 0. , 0. , 0. ],
[ 0. , 0.70710678, 0. , 0. , 0. ],
[ 0. , 0. , 1. , 0. , 0. ],
[ 0. , 0. , 0. , 1. , 0.70710678],
[ 0. , 0. , 0. , 0. , 0.70710678]])
>>> a, b = np.linalg.eig(make_mat([0,0,3])) # repeating 0 is not OK
>>> np.round(b, 3)
array([[ 1. , -1. , 1. , 0.035, 0.447],
[ 0. , 0. , 0. , 0.105, 0.447],
[ 0. , 0. , 0. , 0.314, 0.447],
[ 0. , 0. , 0. , 0.943, 0.447],
[ 0. , 0. , 0. , 0. , 0.447]])
>>> a, b = np.linalg.eig(make_mat([2,3,3])) # repeating other values are not OK
>>> np.round(b, 3)
array([[ 1. , 0.447, -0.229, -0.229, 0.447],
[ 0. , 0.894, -0.688, -0.688, 0.447],
[ 0. , 0. , 0.688, 0.688, 0.447],
[ 0. , 0. , 0. , 0. , 0.447],
[ 0. , 0. , 0. , 0. , 0.447]])
diag**10000
进一步加速。请参见我的另一个回答,其中我在numpy中实现了它。 - Claudiu