我是 ARPACK 新手,我下载了如下脚本
import time
import numpy as np
from scipy.linalg import eigh
from scipy.sparse.linalg import eigs
np.set_printoptions(suppress=True)
n=30
rstart=0
rend=n
A=np.zeros(shape=(n,n))
# first row
if rstart == 0:
A[0, :2] = [2, -1]
rstart += 1
# last row
if rend == n:
A[n-1, -2:] = [-1, 2]
rend -= 1
# other rows
for i in range(rstart, rend):
A[i, i-1:i+2] = [-1, 2, -1]
A[0,8]=30
start_time = time.time()
evals_large, evecs_large = eigs(A, 10, sigma=3.6766133, which='LM')
print evals_large
end_time=time.time()-start_time
print(" Elapsed time: %12f seconds " % end_time)
它解决了一个非常简单的特征值问题(其中的矩阵A
不是对称的,我将A[0,8]
设置为30
)。根据ARPACK结果,最接近3.6766133
(设置中的sigma=3.6766133
)的3个特征值是
[ 3.68402411+0.j 3.82005897+0.j 3.51120293+0.j]
然后我转到MATLAB,并解决相同的特征值问题,结果是
4.144524409923138 + 0.000000000000000i
3.642801014184622 + 0.497479798520641i
3.642801014184622 - 0.497479798520641i
2.372392770347609 + 0.762183281789166i
2.372392770347609 - 0.762183281789166i
3.979221766266502 + 0.000000000000000i
3.918541441830947 + 0.000000000000000i
3.820058967057387 + 0.000000000000000i
3.684024113506185 + 0.000000000000000i
3.511202932803536 + 0.000000000000000i
3.307439963195127 + 0.000000000000000i
3.080265978640102 + 0.000000000000000i
2.832849552917550 + 0.000000000000000i
2.565972630556613 + 0.000000000000000i
2.283744793210587 + 0.000000000000000i
1.996972474451519 + 0.000000000000000i
0.927737801889518 + 0.670252740725955i
0.927737801889518 - 0.670252740725955i
1.714561796881689 + 0.000000000000000i
-0.015193770830045 + 0.264703483268519i
-0.015193770830045 - 0.264703483268519i
1.438919271663752 + 0.000000000000000i
0.019951101383019 + 0.000000000000000i
0.080534338862828 + 0.000000000000000i
0.181591307101504 + 0.000000000000000i
0.318955140475174 + 0.000000000000000i
0.488231021129767 + 0.000000000000000i
0.688030188040126 + 0.000000000000000i
1.171318650526539 + 0.000000000000000i
0.917612528393044 + 0.000000000000000i
显然,第二种模式 3.642801014184622 + 0.497479798520641i
更接近 sigma=3.6766133
,但 ARPACK 没有将其挑出来。
可能是什么问题?你能帮我解决这个问题吗?非常感谢。
最佳答案
首先了解有关 MATLAB 函数的一些事项:
eig
返回的特征值为 NOT sorted 。在[V,D] = eig(A)
中,我们仅保证V
的列是D(i,我)
。另一方面,svd
返回按降序排序的奇异值。d = eigs(A,k)
返回k
最大幅度 特征值。然而,它适用于大型稀疏矩阵,通常不能替代:d = eig(full(A)); d = sort(d, 'descend'); d = d(1:k);
There is no natural ordering 复数。约定是
sort
函数 sorts complex elements first by magnitude(即abs(x)
),然后按[-pi,pi]
间隔上的相位角(即angle(x )
) 如果大小相等。
MATLAB
考虑到这一点,请考虑以下 MATLAB 代码:
% create the same banded matrix you're using
n = 30;
A = spdiags(ones(n,1)*[-1,2,-1], [-1 0 1], n, n);
A(1,9) = 30;
%A = full(A);
% k eigenvalues closest to sigma
k = 10; sigma = 3.6766133;
D = eigs(A, k, sigma);
% lets check they are indeed sorted by distance to sigma
dist = abs(D-sigma);
issorted(dist)
我得到:
>> 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
关于python - 使用ARPACK求解特征值问题,但与Matlab得到的结果不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26520447/