Perché SciPy eigsh () produce autovalori errati in caso di oscillatore armonico?


15

Sto sviluppando un codice più grande per eseguire calcoli con autovalori di enormi matrici sparse, nel contesto della fisica computazionale. Metto alla prova le mie routine contro il semplice oscillatore armonico in una dimensione, poiché gli autovalori sono ben noti analiticamente. Facendo così e confrontando le mie routine con i solutori integrati di SciPy, mi sono imbattuto nella stranezza mostrata nella trama qui sotto. Qui puoi vedere i primi 100 autovalori calcolati numericamente autovalori analitici λ a n aλnumλun'nun'

Attorno all'autovalore numero 40, i risultati numerici iniziano a divergere da quelli analitici. Questo non mi sorprende (non entrerò nel perché qui, a meno che non si presenti nella discussione). Tuttavia, ciò che mi sorprende è che eigsh () produce autovalori degeneri (attorno all'autovalore numero 80). Perché eigsh () si comporta così anche per un numero così piccolo di autovalori?

inserisci qui la descrizione dell'immagine

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

È un comportamento molto curioso. Lo proverò più tardi oggi.
Rafael Reiter,

Ho trovato la risposta In breve: il mio pensiero era sbagliato. Le soluzioni analitiche dell'oscillatore armonico (HOSZ) sono valide senza alcuna limitazione spaziale. Tuttavia, nel codice sopra, la mia casella va da -10 a 10, quindi questo pone una condizione al contorno sulle soluzioni numeriche. Di conseguenza, eigsh () risolve il sistema fornito correttamente. A circa n = 50 (con n che è il numero Quantico principale), le soluzioni analitiche non rientrano più nella casella -10, 10. Ora (dopo qualche riflessione), questo sembra ovvio. Tuttavia, non l'ho visto durante la creazione e il test del codice.
SEB

questo comunque non spiega la degenerazione, vero?
SEB

Risposte:


12

La degenerazione di alcuni autovalori mi sembra il segno distintivo della rottura dell'algoritmo di Lanczos . L'algoritmo di Lanczos è uno dei metodi più comunemente usati per approssimare gli autovalori e gli autovettori delle matrici eremitiche; è ciò che usa scipy.eigsh (), attraverso una chiamata alla libreria ARPACK .

Nell'aritmetica esatta, l'algoritmo di Lanczos produce un insieme di vettori ortogonali, ma nell'aritmetica in virgola mobile questi possono non essere ortogonali e persino diventare linearmente dipendenti. La cosa davvero fastidiosa è che questa perdita di ortogonalità si verifica proprio quando uno degli autovalori approssimativi è converto in uno degli autovalori reali: l'algoritmo si sabota, per così dire. Il risultato è che otterrai alcune coppie spurie di autovalori vicini. Esistono varie correzioni per questo, ad esempio l'uso di Gram-Schmidt per forzare qualsiasi autovettore convergente ad essere ortogonale ad ogni passo.

Tuttavia, nessun metodo è perfetto, specialmente se stai cercando di calcolare l'intero spettro della tua matrice . Quindi, se stai cercando di ottenere i 50 autovalori più piccoli, potresti stare meglio approssimando la funzione d'onda di un vettore con 100 elementi e chiedendo solo eigsh()i primi 50 livelli di energia, piuttosto che usare un vettore con 50 punti e chiedere tutto degli autovalori.

Se vuoi leggere di più, guarda i metodi numerici di Yousef Saad per problemi di autovalori di grandi dimensioni .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.