¿Por qué SciPy eigsh () produce valores propios erróneos en caso de oscilador armónico?


15

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λnortetumetroλunnorteun

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?

ingrese la descripción de la imagen aquí

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()

Ese es un comportamiento muy curioso. Lo probaré más tarde hoy.
Rafael Reiter

Encontré la respuesta. En resumen: mi pensamiento estaba equivocado. Las soluciones analíticas del oscilador armónico (HOSZ) son válidas sin restricciones espaciales. Sin embargo, en el código anterior, mi cuadro se ejecuta de -10 a 10, por lo que esto pone una condición límite en las soluciones numéricas. En consecuencia, eigsh () resuelve el sistema que se le da correctamente. Alrededor de n = 50 (siendo n el número cuántico principal), las soluciones analíticas ya no caben dentro del cuadro -10, 10. Ahora (después de pensarlo un poco), esto parece obvio. Sin embargo, no lo vi mientras construía y probaba el código.
seb

Sin embargo, esto todavía no explica la degeneración, ¿verdad?
seb

Respuestas:


12

La degeneración de algunos valores propios me parece el sello distintivo del colapso del algoritmo de Lanczos . El algoritmo de Lanczos es uno de los métodos más utilizados para aproximar los valores propios y los vectores propios de las matrices hermitianas; es lo que usa scipy.eigsh (), a través de una llamada a la biblioteca ARPACK .

En aritmética exacta, el algoritmo de Lanczos produce un conjunto de vectores ortogonales, pero en aritmética de coma flotante estos pueden dejar de ser ortogonales e incluso volverse linealmente dependientes. Lo realmente molesto es que esta pérdida de ortogonalidad ocurre precisamente cuando uno de los valores propios aproximados ha convergido a uno de los valores propios reales: el algoritmo se sabotea a sí mismo, por así decirlo. El resultado es que obtendrás algunos pares espurios de valores propios cercanos. Hay varias soluciones para esto, por ejemplo, usar Gram-Schmidt para forzar a cualquier vector propio convergente a ser ortogonal en cada paso.

Sin embargo, ningún método es perfecto, especialmente si está tratando de calcular todo el espectro de su matriz . Entonces, si está tratando de obtener los 50 valores propios más pequeños, es mejor que se aproxime a la función de onda mediante un vector con 100 elementos y solo solicite eigsh()los primeros 50 niveles de energía, en lugar de usar un vector con 50 puntos y pedir todos de los autovalores.

Si desea leer más, mire los Métodos numéricos de Yousef Saad para problemas de gran valor propio .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.