关于MATLAB函数首先要做的一些事情:eig返回的特征值是NOTsorted。在[V,D] = eig(A)中,我们只保证V的列是D(i,i)中特征值对应的右特征向量。另一方面,^{}返回按降序排序的单数值。
d = eigs(A,k)返回k最大幅值特征值。但是,它适用于大型稀疏矩阵,通常不能替代:d = eig(full(A));
d = sort(d, 'descend');
d = d(1:k);
MATLAB语言
考虑到这一点,考虑以下MATLAB代码:
^{pr2}$
我得到:>> D
D =
3.684024113506185 + 0.000000000000000i
3.820058967057386 + 0.000000000000000i
3.511202932803535 + 0.000000000000000i
3.918541441830945 + 0.000000000000000i
3.979221766266508 + 0.000000000000000i
3.307439963195125 + 0.000000000000000i
4.144524409923134 + 0.000000000000000i
3.642801014184618 + 0.497479798520640i
3.642801014184618 - 0.497479798520640i
3.080265978640096 + 0.000000000000000i
>> dist
dist =
0.007410813506185
0.143445667057386
0.165410367196465
0.241928141830945
0.302608466266508
0.369173336804875
0.467911109923134
0.498627536953383
0.498627536953383
0.596347321359904
您可以尝试使用密集eig获得类似的结果:% closest k eigenvalues to sigma
ev = eig(full(A));
[~,idx] = sort(ev - sigma);
ev = ev(idx(1:k))
% compare against eigs
norm(D - ev)
可接受的差异很小(接近机器epsilon):>> norm(ev-D)
ans =
1.257079405021441e-14
Python
类似于Python:import numpy as np
from scipy.sparse import spdiags
from scipy.sparse.linalg import eigs
# create banded matrix
n = 30
A = spdiags((np.ones((n,1))*[-1,2,-1]).T, [-1,0,1], n, n).todense()
A[0,8] = 30
# EIGS: k closest eigenvalues to sigma
k = 10
sigma = 3.6766133
D = eigs(A, k, sigma=sigma, which='LM', return_eigenvectors=False)
D = D[::-1]
for x in D:
print '{:.16f}'.format(x)
# EIG
ev,_ = np.linalg.eig(A)
idx = np.argsort(np.abs(ev - sigma))
ev = ev[idx[:k]]
for x in ev:
print '{:.16f}'.format(x)
结果相似:# EIGS
3.6840241135061853+0.0000000000000000j
3.8200589670573866+0.0000000000000000j
3.5112029328035343+0.0000000000000000j
3.9185414418309441+0.0000000000000000j
3.9792217662665070+0.0000000000000000j
3.3074399631951246+0.0000000000000000j
4.1445244099231351+0.0000000000000000j
3.6428010141846170+0.4974797985206380j
3.6428010141846170-0.4974797985206380j
3.0802659786400950+0.0000000000000000j
# EIG
3.6840241135061880+0.0000000000000000j
3.8200589670573906+0.0000000000000000j
3.5112029328035339+0.0000000000000000j
3.9185414418309468+0.0000000000000000j
3.9792217662665008+0.0000000000000000j
3.3074399631951201+0.0000000000000000j
4.1445244099231271+0.0000000000000000j
3.6428010141846201+0.4974797985206384j
3.6428010141846201-0.4974797985206384j
3.0802659786400906+0.0000000000000000j