Kann ein angenäherter Jacobi mit endlichen Differenzen Instabilität in der Newton-Methode verursachen?


13

Ich habe einen Rückwärts-Euler-Löser in Python 3 implementiert (mit Numpy). Zu meiner eigenen Bequemlichkeit und als Übung habe ich auch eine kleine Funktion geschrieben, die eine endliche Differenzapproximation des Gradienten berechnet, so dass ich den Jacobian nicht immer analytisch bestimmen muss (wenn es überhaupt möglich ist!).

Unter Verwendung der in Ascher und Petzold 1998 bereitgestellten Beschreibungen habe ich diese Funktion geschrieben, die den Gradienten an einem gegebenen Punkt x bestimmt:

def jacobian(f,x,d=4):
    '''computes the gradient (Jacobian) at a point for a multivariate function.

    f: function for which the gradient is to be computed
    x: position vector of the point for which the gradient is to be computed
    d: parameter to determine perturbation value eps, where eps = 10^(-d).
        See Ascher und Petzold 1998 p.54'''

    x = x.astype(np.float64,copy=False)
    n = np.size(x)
    t = 1 # Placeholder for the time step
    jac = np.zeros([n,n])
    eps = 10**(-d)
    for j in np.arange(0,n):
        yhat = x.copy()
        ytilde = x.copy()
        yhat[j] = yhat[j]+eps
        ytilde[j] = ytilde[j]-eps
        jac[:,j] = 1/(2*eps)*(f(t,yhat)-f(t,ytilde))
    return jac

Ich habe diese Funktion getestet, indem ich eine multivariate Funktion für das Pendel genommen und den symbolischen Jacobi mit dem numerisch bestimmten Gradienten für einen Bereich von Punkten verglichen habe. Ich war mit den Testergebnissen zufrieden, der Fehler lag bei 1e-10. Als ich die ODE für das Pendel mit dem angenäherten Jacobian löste, funktionierte es auch sehr gut; Ich konnte keinen Unterschied zwischen den beiden feststellen.

Dann habe ich versucht, es mit der folgenden PDE (Fisher-Gleichung in 1D) zu testen:

tu=x(kxu)+λ(u(C-u))

unter Verwendung einer endlichen Differenzdiskretisierung.

Jetzt explodiert Newtons Methode im ersten Zeitschritt:

/home/sfbosch/Fisher-Equation.py:40: RuntimeWarning: overflow encountered in multiply
  du = (k/(h**2))*np.dot(K,u) + lmbda*(u*(C-u))
./newton.py:31: RuntimeWarning: invalid value encountered in subtract
  jac[:,j] = 1/(2*eps)*(f(t,yhut)-f(t,yschlange))
Traceback (most recent call last):
  File "/home/sfbosch/Fisher-Equation.py", line 104, in <module>
    fisher1d(ts,dt,h,L,k,C,lmbda)
  File "/home/sfbosch/Fisher-Equation.py", line 64, in fisher1d
    t,xl = euler.implizit(fisherode,ts,u0,dt)
  File "./euler.py", line 47, in implizit
    yi = nt.newton(g,y,maxiter,tol,Jg)
  File "./newton.py", line 54, in newton
    dx = la.solve(A,b)
  File "/usr/lib64/python3.3/site-packages/scipy/linalg/basic.py", line 73, in solve
    a1, b1 = map(np.asarray_chkfinite,(a,b))
  File "/usr/lib64/python3.3/site-packages/numpy/lib/function_base.py", line 613, in asarray_chkfinite
    "array must not contain infs or NaNs")
ValueError: array must not contain infs or NaNs

Dies passiert für eine Vielzahl von eps-Werten, aber seltsamerweise nur, wenn die räumliche Schrittgröße und die zeitliche Schrittgröße der PDE so eingestellt sind, dass die Courant-Friedrichs-Lewy-Bedingung nicht erfüllt ist. Ansonsten klappt es. (Dies ist das Verhalten, das Sie beim Lösen mit Forward Euler erwarten würden!)

Der Vollständigkeit halber ist hier die Funktion für die Newton-Methode:

def newton(f,x0,maxiter=160,tol=1e-4,jac=jacobian):
    '''Newton's Method.

    f: function to be evaluated
    x0: initial value for the iteration
    maxiter: maximum number of iterations (default 160)
    tol: error tolerance (default 1e-4)
    jac: the gradient function (Jacobian) where jac(fun,x)'''

    x = x0
    err = tol + 1
    k = 0
    t = 1 # Placeholder for the time step
    while err > tol and k < maxiter:
        A = jac(f,x)
        b = -f(t,x)
        dx = la.solve(A,b)
        x = x + dx
        k = k + 1
        err = np.linalg.norm(dx)
    if k >= maxiter:
        print("Maxiter reached. Result may be inaccurate.")
        print("k = %d" % k)
    return x

(Die Funktion la.solve ist scipy.linalg.solve.)

Ich bin zuversichtlich, dass meine Rückwärts-Euler-Implementierung in Ordnung ist, da ich sie mit einer Funktion für den Jacobi getestet habe und stabile Ergebnisse erzielt habe.

Ich kann im Debugger sehen, dass newton () 35 Iterationen verwaltet, bevor der Fehler auftritt. Diese Zahl bleibt für jedes EPS, das ich ausprobiert habe, gleich.

Eine zusätzliche Beobachtung: Wenn ich den Gradienten mit der FDA und einer Funktion unter Verwendung der Anfangsbedingung als Eingabe berechne und die beiden vergleiche, während die Größe von Epsilon variiert, wächst der Fehler mit abnehmendem Epsilon. Ich würde erwarten, dass es zuerst groß wird, dann kleiner und dann wieder größer, wenn epsilon schrumpft. Ein Fehler in meiner Implementierung des Jacobian ist also eine vernünftige Annahme, aber wenn ja, ist er so subtil, dass ich ihn nicht sehen kann. EDIT: Ich habe jacobian () modifiziert, um Forward anstelle von zentralen Unterschieden zu verwenden, und jetzt beobachte ich die erwartete Entwicklung des Fehlers. Newton () konvergiert jedoch immer noch nicht. Wenn ich dx in der Newton-Iteration betrachte, sehe ich, dass es nur wächst, es gibt nicht einmal eine Fluktuation: Es verdoppelt sich fast (Faktor 1,9) mit jedem Schritt, wobei der Faktor zunehmend größer wird.

Ascher und Petzold erwähnen, dass Differenzapproximationen für den Jakobianer nicht immer gut funktionieren. Kann ein angenäherter Jacobianer mit endlichen Differenzen eine Instabilität in Newtons Methode verursachen? Oder liegt die Ursache woanders? Wie könnte ich dieses Problem sonst angehen?


1
"Ich bin zuversichtlich, dass meine Rückwärts-Euler-Implementierung in Ordnung ist, da ich sie mit einer Funktion für den Jacobian getestet habe und stabile Ergebnisse erzielt habe." Bitte klären Sie. Wollen Sie damit sagen, dass Sie dasselbe Problem mit einem exakten Jacobian ausführen und die Lösung zur exakten Lösung der PDE konvergiert? Das ist eine wichtige Information.
David Ketcheson

@ DavidKetcheson Ja, das ist, was ich sage. Entschuldigung, wenn meine Terminologie falsch oder unvollständig ist. (Ich nehme an, ich hätte auch sagen sollen: "Ich erhalte stabile und erwartete Ergebnisse.")
Stephen Bosch

Antworten:


3

Mehr ein langer Kommentar als alles andere:

Unter Verwendung der in Ascher und Petzold 1998 bereitgestellten Beschreibungen habe ich diese Funktion geschrieben, die den Gradienten an einem gegebenen Punkt x bestimmt:

Schauen Sie sich den Code für die Differenzquotienten-Approximation von SUNDIALS an, um eine bessere Vorstellung davon zu erhalten, was Sie in einer Implementierung tun sollten. Ascher und Petzold ist ein gutes Buch für den Einstieg, aber SUNDIALS wird tatsächlich in der Produktionsarbeit verwendet und wurde daher besser getestet. (Außerdem ist SUNDIALS mit DASPK verwandt, an dem Petzold gearbeitet hat.)

Ascher und Petzold erwähnen, dass Differenzapproximationen für den Jakobianer nicht immer gut funktionieren. Kann ein angenäherter Jacobianer mit endlichen Differenzen eine Instabilität in Newtons Methode verursachen?

Empirisch können ungefähre Jacobianer Konvergenzfehler in Newtons Methode verursachen. Ich weiß nicht, dass ich sie als "Instabilität" bezeichnen würde; In einigen Fällen ist es einfach nicht möglich, die gewünschten Fehlertoleranzen in den Abbruchkriterien zu erreichen. In anderen Fällen kann sich dies als Instabilität manifestieren. Ich bin mir fast sicher, dass es ein quantitativeres Ergebnis zu diesem Phänomen in Highams Buch über numerische Methoden oder in der Diskussion von Hairer und Wanner über W-Methoden gibt.

Oder liegt die Ursache woanders? Wie könnte ich dieses Problem sonst angehen?

Es hängt davon ab, wo Sie den Fehler für möglich halten. Wenn Sie sehr zuversichtlich sind, Euler rückwärts zu implementieren, würde ich dort nicht anfangen. Die Erfahrung hat mich bei der Implementierung numerischer Methoden paranoid gemacht. Wenn ich es also wäre, würde ich damit beginnen, ein paar wirklich grundlegende Testprobleme zu codieren (ein paar nicht steife und steife lineare Probleme, die Wärmegleichung mit einer zentrierten Finite-Differenzen-Approximation). Dinge wie das) und ich würde die Methode der hergestellten Lösungen verwenden, um mir zu versichern, dass ich weiß, was die Lösung sein wird und womit ich mich vergleichen sollte.

Sie haben jedoch bereits einige davon getan:

Ich bin zuversichtlich, dass meine Rückwärts-Euler-Implementierung in Ordnung ist, da ich sie mit einer Funktion für den Jacobi getestet habe und stabile Ergebnisse erzielt habe.

Das wäre das nächste, was ich testen würde: Verwenden Sie einen analytischen Jacobian. Danach können Sie auch die extremen Eigenwerte Ihres Jacobi-Differenzenwerts betrachten, wenn Sie sich nicht in der instabilen Region des Rückwärts-Eulers befinden. Ein Blick auf die extremen Eigenwerte Ihres analytischen Jacobi als Vergleichsbasis könnte Ihnen einen Einblick geben. Vorausgesetzt, alle checken aus, ist das Problem wahrscheinlich im Newton gelöst.


Vielen Dank für die durchdachte Analyse (plus dem SUNDIALS-Hinweis und den alternativen Quellen). Mein Professor schlug vor, Lambda = 0 zu setzen, und argumentierte, dass die FDA der PDE dann linear wird, sodass wir erwarten würden, dass der FDA-Jacobian dem analytischen Jacobian entspricht. Wenn ich das mache, schafft es drei Zeitschritte, wobei newton () jedes Mal auf maxiter trifft, bevor es schließlich wie zuvor explodiert.
Stephen Bosch

Er sagte auch, dass es nicht üblich sei, angenäherte Jacobianer zur Lösung von PDEs zu verwenden, und schlug vor, dass es aufgrund der vielen Freiheitsgrade Probleme geben könnte (ohne eine Erklärung anzugeben, obwohl er sich gerade die Diskussion von Hairer und Wanner über W-Methoden angeschaut hatte, Ich kann sehen, dass es wahrscheinlich nicht trivial ist.
Stephen Bosch

1
Die Aussage Ihres Professors ist in Anbetracht der Menge an Literatur zu diesem Thema, zum Beispiel dieser berühmten Rezension von Knoll und Keyes, etwas überraschend . Wahrscheinlich hätte ich dieses Papier in meiner Antwort zitieren sollen, da die Quellen in der Bibliographie auch bei der Diagnose Ihrer Probleme hilfreich sein können.
Geoff Oxberry
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.