我尝试熟悉诸如Lanczos之类的迭代特征值求解器。所以我尝试根据wiki直接将其重写为python。但这似乎不起作用。
问题:
- 它非常接近最大的特征值矩阵
- 但是通过投影三对角矩阵的解获得的其余特征值在区间上均匀分布,原始矩阵
- 我希望它会找到大特征值
- 向量(矩阵)由Lancozs迭代生成的似乎仍然相互正交,所以我猜Lancozs的数值不稳定不是问题
Python代码:
def Lanczos( A, v, m=100 ):
n = len(v)
if m>n: m = n;
# from here https://en.wikipedia.org/wiki/Lanczos_algorithm
V = np.zeros( (m,n) )
T = np.zeros( (m,m) )
vo = np.zeros(n)
beta = 0
for j in range( m-1 ):
w = np.dot( A, v )
alfa = np.dot( w, v )
w = w - alfa * v - beta * vo
beta = np.sqrt( np.dot( w, w ) )
vo = v
v = w / beta
T[j,j ] = alfa
T[j,j+1] = beta
T[j+1,j] = beta
V[j,:] = v
w = np.dot( A, v )
alfa = np.dot( w, v )
w = w - alfa * v - beta * vo
T[m-1,m-1] = np.dot( w, v )
V[m-1] = w / np.sqrt( np.dot( w, w ) )
return T, V
# ---- generate matrix A
n = 50; m=10
sqrtA = np.random.rand( n,n ) - 0.5
A = np.dot( sqrtA, np.transpose(sqrtA) )
# ---- full solve for eigenvalues for reference
esA, vsA = np.linalg.eig( A )
# ---- approximate solution by Lanczos
v0 = np.random.rand( n ); v0 /= np.sqrt( np.dot( v0, v0 ) )
T, V = Lanczos( A, v0, m=m )
esT, vsT = np.linalg.eig( T )
VV = np.dot( V, np.transpose( V ) ) # check orthogonality
#print "A : "; print A
print "T : "; print T
print "VV :"; print VV
print "esA :"; print np.sort(esA)
print "esT : "; print np.sort(esT)
plt.plot( esA, np.ones(n)*0.2, '+' )
plt.plot( esT, np.ones(m)*0.1, '+' )
plt.ylim(0,1)
plt.show( m )
插图:
- 蓝色 - 矩阵的特征值
- 绿色 - 矩阵的特征值