Я розробляю якийсь більший код для виконання обчислень власних значень величезних розріджених матриць в контексті обчислювальної фізики. Я перевіряю свої підпрограми проти простого гармонічного осцилятора в одному вимірі, оскільки власні значення добре відомі аналітично. Роблячи це і порівнюючи власну процедуру з вбудованими рішеннями 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()