Estoy desarrollando un código más grande para realizar cálculos de valores propios de enormes matrices dispersas, en el contexto de la física computacional. Pruebo mis rutinas contra el oscilador armónico simple en una dimensión, ya que los valores propios son bien conocidos analíticamente. Al hacerlo y al comparar mis propias rutinas con los solucionadores incorporados de SciPy, me he encontrado con la rareza que se muestra en la siguiente trama. Aquí puede ver los primeros 100 valores propios calculados numéricamente y valores propios analíticos λ a n a
Alrededor del valor propio número 40, los resultados numéricos comienzan a diferir de los analíticos. Esto no me sorprende (no voy a entrar en por qué aquí, a menos que aparezca en la discusión). Sin embargo, lo que me sorprende es que eigsh () produce valores propios degenerados (alrededor del número de valor propio 80). ¿Por qué eigsh () se comporta así incluso con un número tan pequeño de valores propios?
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()