In meiner Antwort auf eine Frage zu MSE bezüglich einer 2D-Hamiltonschen Physiksimulation habe ich vorgeschlagen, einen symplektischen Integrator höherer Ordnung zu verwenden .
Dann hielt ich es für eine gute Idee, die Auswirkungen verschiedener Zeitschritte auf die globale Genauigkeit von Methoden mit unterschiedlichen Ordnungen zu demonstrieren, und schrieb und führte ein Python / Pylab-Skript zu diesem Zweck aus. Zum Vergleich habe ich gewählt:
- ( leap2 ) Wikipedia's Beispiel 2. Ordnung, mit dem ich vertraut bin, obwohl ich es unter dem Namen leapfrog kenne ,
- ( ruth3 ) Ruths symplektischer Integrator 3. Ordnung ,
- ( ruth4 ) Ruths symplektischer Integrator 4. Ordnung .
Das Seltsame ist, egal welchen Zeitschritt ich wähle, Ruths Methode 3. Ordnung scheint in meinem Test genauer zu sein als Ruths Methode 4. Ordnung, selbst um eine Größenordnung.
Meine Frage ist daher: Was mache ich hier falsch? Details unten.
Die Methoden entfalten ihre Stärke in Systemen mit trennbaren Hamiltonianern, dh solchen, die als
wobei alle Positionskoordinaten umfasst ,
die konjugierten Impulse umfasst,
die Kinetik darstellt Energie und potentielle Energie.
In unserem Setup können wir Kräfte und Impulse durch die Massen normalisieren, auf die sie angewendet werden. So werden Kräfte zu Beschleunigungen und Impulse zu Geschwindigkeiten.
Die symplektischen Integratoren kommen mit speziellen (gegebenen, konstanten) Koeffizienten, die ich mit und . Mit diesen Koeffizienten nimmt ein Schritt zum Entwickeln des Systems vom Zeitpunkt zum Zeitpunkt die Form an
Für :
- Berechnen Sie den Vektor aller Beschleunigungen unter Berücksichtigung des Vektors aller Positionen
- Ändern Sie den Vektor aller Geschwindigkeiten um
- Ändern Sie den Vektor aller Positionen um
Die Weisheit liegt nun in den Koeffizienten. Dies sind
Zum Testen habe ich das 1D-Anfangswertproblem
das einen trennbaren Hamilton-Operator hat. Hier werden mit identifiziert .
Ich habe das IVP mit den obigen Methoden über mit einer Schrittgröße von mit einer ganzen Zahl die irgendwo zwischen und . Unter Berücksichtigung der Geschwindigkeit von leap2 habe ich für diese Methode verdreifacht . Ich habe dann die resultierenden Kurven im Phasenraum aufgezeichnet und auf gezoomt, wo die Kurven idealerweise wieder bei ankommen sollten .N(1,0)t=2π
Hier sind Diagramme und Zooms für und :
Für kommt Sprung2 mit der Schrittgröße näher zu Hause als ruth4 mit der Schrittgröße . Für , ruth4 gewinnt über leap2 . Allerdings kommt ruth3 mit der gleichen Schrittgröße wie ruth4 in allen Einstellungen, die ich bisher getestet habe , viel näher zu Hause an als die beiden anderen.2 π 2π
Hier ist das Python / Pylab-Skript:
import numpy as np
import matplotlib.pyplot as plt
def symplectic_integrate_step(qvt0, accel, dt, coeffs):
q,v,t = qvt0
for ai,bi in coeffs.T:
v += bi * accel(q,v,t) * dt
q += ai * v * dt
t += ai * dt
return q,v,t
def symplectic_integrate(qvt0, accel, t, coeffs):
q = np.empty_like(t)
v = np.empty_like(t)
qvt = qvt0
q[0] = qvt[0]
v[0] = qvt[1]
for i in xrange(1, len(t)):
qvt = symplectic_integrate_step(qvt, accel, t[i]-t[i-1], coeffs)
q[i] = qvt[0]
v[i] = qvt[1]
return q,v
c = np.math.pow(2.0, 1.0/3.0)
ruth4 = np.array([[0.5, 0.5*(1.0-c), 0.5*(1.0-c), 0.5],
[0.0, 1.0, -c, 1.0]]) / (2.0 - c)
ruth3 = np.array([[2.0/3.0, -2.0/3.0, 1.0], [7.0/24.0, 0.75, -1.0/24.0]])
leap2 = np.array([[0.5, 0.5], [0.0, 1.0]])
accel = lambda q,v,t: -q
qvt0 = (1.0, 0.0, 0.0)
tmax = 2.0 * np.math.pi
N = 36
fig, ax = plt.subplots(1, figsize=(6, 6))
ax.axis([-1.3, 1.3, -1.3, 1.3])
ax.set_aspect('equal')
ax.set_title(r"Phase plot $(y(t),y'(t))$")
ax.grid(True)
t = np.linspace(0.0, tmax, 3*N+1)
q,v = symplectic_integrate(qvt0, accel, t, leap2)
ax.plot(q, v, label='leap2 (%d steps)' % (3*N), color='black')
t = np.linspace(0.0, tmax, N+1)
q,v = symplectic_integrate(qvt0, accel, t, ruth3)
ax.plot(q, v, label='ruth3 (%d steps)' % N, color='red')
q,v = symplectic_integrate(qvt0, accel, t, ruth4)
ax.plot(q, v, label='ruth4 (%d steps)' % N, color='blue')
ax.legend(loc='center')
fig.show()
Ich habe bereits nach einfachen Fehlern gesucht:
- Kein Wikipedia-Tippfehler. Ich habe insbesondere die Referenzen überprüft ( 1 , 2 , 3 ).
- Ich habe die richtige Koeffizientenfolge. Wenn Sie mit der Bestellung von Wikipedia vergleichen, beachten Sie, dass die Sequenzierung der Operatoranwendung von rechts nach links funktioniert. Meine Nummerierung stimmt mit Candy / Rozmus überein . Und wenn ich trotzdem eine andere Bestellung versuche, werden die Ergebnisse schlechter.
Mein Verdacht:
- Falsche Schrittgrößenreihenfolge: Vielleicht hat Ruths Schema 3. Ordnung irgendwie viel kleinere implizite Konstanten, und wenn die Schrittgröße wirklich klein gemacht würde, würde die Methode 4. Ordnung gewinnen? Aber ich habe sogar ausprobiert , und die Methode 3. Ordnung ist immer noch überlegen.
- Falscher Test: Etwas Besonderes an meinem Test lässt Ruths Methode 3. Ordnung wie eine Methode höherer Ordnung verhalten?
quelle
Antworten:
Auf Kirills Vorschlag hin führte ich den Test mit aus einer Liste von ungefähr geometrisch ansteigenden Werten durch und berechnete für jedes den Fehler als wobei die Approximation darstellt erhalten durch numerische Integration. Hier ist das Ergebnis in einem Log-Log-Plot:N ϵ ( N ) = ‖ ˜ z ( 2 π ) - ˜ z ( 0 ) ‖ 2N N ˜ z
Also hat ruth3 tatsächlich die gleiche Ordnung wie ruth4 für diesen Testfall und impliziert Konstanten von nur der Größe.14 1100
Interessant. Ich muss weiter nachforschen und vielleicht andere Tests versuchen.
Übrigens, hier sind die Ergänzungen zum Python-Skript für den Fehlerplot:
quelle
Das Zeichnen des Fehlers von , über das gesamte Intervall, skaliert mit der Potenz der Schrittgröße, die durch die erwartete Reihenfolge gegeben ist, ergibt die Diagrammeq¨=−q q(0)=1,q˙(0)=0
Wie erwartet nähern sich die Graphen für eine zunehmende Anzahl von Teilintervallen zunehmend einer Grenzkurve an, die der führende Fehlerkoeffizient ist. In allen außer einem Diagramm ist diese Konvergenz sichtbar schnell, es gibt fast keine Divergenz. Dies bedeutet, dass selbst bei relativ großen Schrittgrößen der führende Fehlerterm alle anderen Terme dominiert.
Bei der Ruth-Methode 3. Ordnung scheint der führende Koeffizient der Komponente Null zu sein, die sichtbare Grenzkurve liegt nahe oder gleich der horizontalen Achse. Die sichtbaren Grafiken zeigen deutlich die Dominanz des Fehlerterms 4. Ordnung. Die Skalierung für einen Fehler 4. Ordnung ergibt eine Darstellung ähnlich den anderen.p
Wie man sehen kann, ist in allen 3 Fällen der Fehlerkoeffizient der führenden Ordnung in der Komponente bei nach einer vollen Periode Null . Bei der Kombination der Fehler beider Komponenten dominiert somit das Verhalten der Komponente, was fälschlicherweise den Eindruck einer Methode 4. Ordnung im Loglog-Plot erweckt.q t=2π p
Ein maximaler Koeffizient in der Komponente kann um . Das Loglog-Diagramm dort sollte die korrekten globalen Fehlerreihenfolgen widerspiegeln.q 3π/2
Dass das Verschwinden des Fehlerterms 3. Grades in Ruth3p ein Artefakt der Einfachheit der linearen Gleichung ist, zeigt das nichtlineare Beispiel , mit den entsprechenden Darstellungenq¨=−sin(q) q(0)=1.3, q˙(0)=0
quelle