我使用python(scipy)来计算对称实矩阵的特征值。我目前正在使用
scipy.linalg.eigvalsh
用于计算特征值(http://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.eigvalsh.html#scipy.linalg.eigvalsh)的函数。查看eigvalsh的源代码,看起来python会调用fortran包。它还在文档中提到,计算中的错误将不会收敛。
我的问题是:什么是收敛标准?我能改变它(相对容易)吗?
在我的具体应用中,我计算了一系列矩阵的特征值,我注意到几个特征值之间的强相关性。我想知道相关性是否完全纯粹是因为数值原因。如果我可以加强收敛标准,那么我可以看出依赖性是否会增加。
答案 0 :(得分:1)
如果我正确阅读源代码,则使用LAPACK函数dsyevr()。如果我理解正确,摆弄它的参数不一定会让你获得更高的准确性。如果您需要高准确度,可以尝试mpmath:
import numpy as np
from mpmath import mp
print("*** Scipy calculations: ***")
# Generate matrix:
n = 25
AA = np.random.randn(n, n)
HH = np.dot(AA, AA.T)
# Calculate eigenvalues and -vectors:
w, VV = eigh(HH) # eigvalsh() calls also eigh()
# Check Result:
HH2 = np.dot(VV, np.diag(w).dot(VV.T))
dHH = HH - HH2
elem_diff_max = np.abs(HH-HH2).max()
print("Elements differ by maximally {}".format(np.abs(dHH).max()))
print("Froebenius norm: {}".format(np.linalg.norm(HH-HH2,'fro')))
print("")
print("*** Mpmath calculations (very slow): *** ")
mp.dps = 40 # number of precision digits for mpmath
mHH = mp.matrix(HH) # take previous atrix
mw, mVV = mp.eigh(mHH) # and do eigem decomposition
# Check rsults:
mHH2 = mVV*mp.diag(mw)*mVV.T
mdHH = mHH-mHH2
#Curiously I could not figure out how to determine abs(mdHH).max(),
hmax = mp.mpf(0)
for r in mdHH.tolist():
for c in r:
mc = c if c >= 0 else -c
hmax = mc if mc > hmax else hmax
print("Elements differ by maximally {}".format(hmax))
print("Froebenius norm: {}".format(mp.norm(mdHH)))
# Sample output (differs because of randn()):
#
# *** Scipy calculations: ***
# Elements differ by maximally 6.48370246381e-14
# Froebenius norm: 4.90996840307e-13
# *** Mpmath calculations (very slow): ***
# Elements differ by maximally 5.510129769479472693603452518229276614775e-39
# Froebenius norm: 3.772588954060141733111171961647528674136e-38