Я разрабатываю некоторый более крупный код для выполнения вычислений по собственным значениям огромных разреженных матриц в контексте вычислительной физики. Я проверяю свои процедуры против простого гармонического осциллятора в одном измерении, поскольку собственные значения хорошо известны аналитически. Делая это и сравнивая мои собственные процедуры со встроенными решателями SciPy, я столкнулся со странностью, показанной на графике ниже. Здесь вы можете увидеть первые 100 численно вычисленных собственных значений и аналитических собственных значений λ a n a
Вокруг собственного значения 40 числовые результаты начинают расходиться с аналитическими. Меня это не удивляет (я не буду вдаваться в причину, если только это не будет обсуждаться). Однако, что удивляет меня, так это то, что eigsh () создает вырожденные собственные значения (около 80 собственных значений). Почему eigsh () ведет себя так даже для такого небольшого числа собственных значений?
import numpy as np
from scipy.sparse.linalg import eigsh
import myFunctions as myFunc
import matplotlib.pyplot as plt
#discretize x-axis
N = 100
xmin = -10.
xmax = 10.
accuracy = 1e-5
#stepsize
h = (xmax - xmin) / (N + 1.)
#exclude first and last points since we force wave function to be zero there
x = np.linspace(-10. + h,10. - h,N)
#create potential
V = x**2
def fivePoint(N,h,V):
C0 = (np.ones(N))*30. / (12. * h * h) + V
C1 = (np.ones(N)) * (-16.) / (12. * h * h)
C2 = (np.ones(N)) / (12. * h * h)
H = sp.spdiags([C2, C1, C0, C1, C2],[-2, -1, 0, 1, 2],N,N)
return H
H = myFunc.fivePoint(N,h,V)
eigval,eigvec = eigsh(H, k=N-1, which='SM', tol=accuracy)
#comparison analytical and numerical eigenvalues
xAxes = np.linspace(0,len(eigval)-1,len(eigval))
analyticalEigval = 2. * (xAxes + 0.5)
plt.figure()
plt.plot(xAxes,eigval, '+', label=r"$\lambda_{num}$")
plt.plot(xAxes,analyticalEigval, label=r"$\lambda_{ana}$")
plt.xlabel("Number of Eigenvalue")
plt.ylabel("Eigenvalue")
plt.legend(loc=4)
plt.title("eigsh()-method: Comparison of $\lambda_{num}$ and $\lambda_{ana}$")
plt.show()