scipy.optimize.elementwise.

find_root#

scipy.optimize.elementwise.find_root(f, init, /, *, args=(), tolerances=None, maxiter=None, callback=None)[Quelle]#

Findet die Wurzel einer monotonen, reellwertigen Funktion einer reellen Variablen.

Für jedes Element der Ausgabe von f sucht find_root die skalare Wurzel, die das Element zu 0 macht. Diese Funktion verwendet derzeit Chandrupatlas Einklammerungsalgorithmus [1] und erfordert daher, dass das Argument init eine Klammer um die Wurzel bereitstellt: Die Funktionswerte an den beiden Endpunkten müssen entgegengesetzte Vorzeichen haben.

Bei einer gültigen Klammer konvergiert find_root garantiert zu einer Lösung, die die angegebenen tolerances erfüllt, wenn die Funktion innerhalb der Klammer stetig ist.

Diese Funktion arbeitet elementweise, wenn init und args (broadcastfähige) Arrays enthalten.

Parameter:
faufrufbar

Die Funktion, deren Wurzel gesucht wird. Die Signatur muss lauten

f(x: array, *args) -> array

wobei jedes Element von x eine endliche reelle Zahl ist und args ein Tupel ist, das eine beliebige Anzahl von Arrays enthalten kann, die mit x broadcastfähig sind.

f muss eine elementweise Funktion sein: jedes Element f(x)[i] muss für alle Indizes i gleich f(x[i]) sein. Sie darf das Array x oder die Arrays in args nicht verändern.

find_root sucht ein Array x, sodass f(x) ein Array von Nullen ist.

init2-Tupel aus float array_like

Die untere und obere Grenze einer Klammer, die die gesuchte Wurzel umschließt. Eine Klammer ist gültig, wenn die Arrays xl, xr = init die Bedingung xl < xr und elementweise sign(f(xl)) == -sign(f(xr)) erfüllen. Die Arrays müssen untereinander und mit args broadcastfähig sein.

argstuple of array_like, optional

Zusätzliche positionale Array-Argumente, die an f übergeben werden. Arrays müssen untereinander und mit den Arrays von init broadcastfähig sein. Wenn die aufgerufene Funktion, für die die Wurzel gesucht wird, Argumente benötigt, die nicht mit x broadcastfähig sind, wrappen Sie diese Funktion mit f, sodass f nur x und broadcastfähige *args akzeptiert.

tolerancesDictionary von Floats, optional

Absolute und relative Toleranzen für die Wurzel und den Funktionswert. Gültige Schlüssel des Dictionaries sind

  • xatol - absolute Toleranz für die Wurzel

  • xrtol - relative Toleranz für die Wurzel

  • fatol - absolute Toleranz für den Funktionswert

  • frtol - relative Toleranz für den Funktionswert

Siehe Hinweise für Standardwerte und explizite Abbruchbedingungen.

maxiterint, optional

Die maximale Anzahl von Iterationen des Algorithmus, die durchgeführt werden sollen. Der Standardwert ist die maximal mögliche Anzahl von Bisektionen innerhalb der (normalen) Gleitkommazahlen des entsprechenden dtypes.

callbackcallable, optional

Eine optionale, vom Benutzer bereitgestellte Funktion, die vor der ersten Iteration und nach jeder Iteration aufgerufen wird. Aufgerufen wird sie als callback(res), wobei res ein _RichResult ähnlich dem von find_root zurückgegebenen ist (aber die Werte aller Variablen des aktuellen Iteranden enthält). Wenn callback eine StopIteration auslöst, wird der Algorithmus sofort beendet und find_root gibt ein Ergebnis zurück. callback darf res oder seine Attribute nicht verändern.

Rückgabe:
res_RichResult

Ein Objekt, das einer Instanz von scipy.optimize.OptimizeResult ähnelt, mit den folgenden Attributen. Die Beschreibungen sind so formuliert, als wären die Werte Skalare; wenn f jedoch ein Array zurückgibt, sind die Ausgaben Arrays derselben Form.

successBool-Array

True, wenn der Algorithmus erfolgreich beendet wurde (Status 0); andernfalls False.

statusInteger-Array

Eine Ganzzahl, die den Exit-Status des Algorithmus darstellt.

  • 0 : Der Algorithmus konvergierte gegen die angegebenen Toleranzen.

  • -1 : Die anfängliche Klammer war ungültig.

  • -2 : Die maximale Anzahl von Iterationen wurde erreicht.

  • -3 : Ein nicht-endlicher Wert wurde angetroffen.

  • -4 : Die Iteration wurde durch callback beendet.

  • 1 : Der Algorithmus läuft normal (nur in callback).

xfloat array

Die Wurzel der Funktion, falls der Algorithmus erfolgreich beendet wurde.

f_xfloat array

Der Wert von f ausgewertet an x.

nfevInteger-Array

Die Anzahl der Abszissen, an denen f zur Bestimmung der Wurzel ausgewertet wurde. Dies unterscheidet sich von der Anzahl der Male, die f *aufgerufen* wird, da die Funktion in einem einzigen Aufruf an mehreren Punkten ausgewertet werden kann.

nitint array

Die Anzahl der Iterationen des Algorithmus, die durchgeführt wurden.

bracketTupel aus float arrays

Die untere und obere Grenze der endgültigen Klammer.

f_bracketTupel aus float arrays

Der Wert von f ausgewertet an der unteren und oberen Grenze der Klammer.

Siehe auch

bracket_root

Hinweise

Implementiert basierend auf Chandrupatlas Originalarbeit [1].

Sei

  • a, b = init die linke und rechte Grenze der anfänglichen Klammer,

  • xl und xr die linke und rechte Grenze der endgültigen Klammer,

  • xmin = xl if abs(f(xl)) <= abs(f(xr)) else xr die endgültige Klammergrenze mit dem kleineren Funktionswert und

  • fmin0 = min(f(a), f(b)) das Minimum der beiden Funktionswerte, die an den anfänglichen Klammergrenzen ausgewertet wurden.

Dann gilt der Algorithmus als konvergiert, wenn

  • abs(xr - xl) < xatol + abs(xmin) * xrtol oder

  • fun(xmin) <= fatol + abs(fmin0) * frtol.

Dies ist äquivalent zur Abbruchbedingung, die in [1] beschrieben wird, mit xrtol = 4e-10, xatol = 1e-5 und fatol = frtol = 0. Die Standardwerte des Dictionaries tolerances sind jedoch xatol = 4*tiny, xrtol = 4*eps, frtol = 0 und fatol = tiny, wobei eps und tiny die Präzision und die kleinste normale Zahl des Ergebnisses dtype der Funktionseingaben und -ausgaben sind.

Referenzen

[1] (1,2,3)

Chandrupatla, Tirupathi R. „A new hybrid quadratic/bisection algorithm for finding the zero of a nonlinear function without using derivatives“. Advances in Engineering Software, 28(3), 145-149. https://doi.org/10.1016/s0965-9978(96)00051-8

Beispiele

Angenommen, wir möchten die Wurzel der folgenden Funktion finden.

>>> def f(x, c=5):
...     return x**3 - 2*x - c

Zuerst müssen wir eine gültige Klammer finden. Die Funktion ist nicht monoton, aber bracket_root kann möglicherweise eine Klammer bereitstellen.

>>> from scipy.optimize import elementwise
>>> res_bracket = elementwise.bracket_root(f, 0)
>>> res_bracket.success
True
>>> res_bracket.bracket
(2.0, 4.0)

Tatsächlich haben die Funktionswerte an den Klammergrenzen entgegengesetzte Vorzeichen.

>>> res_bracket.f_bracket
(-1.0, 51.0)

Sobald wir eine gültige Klammer haben, kann find_root verwendet werden, um eine präzise Wurzel zu erhalten.

>>> res_root = elementwise.find_root(f, res_bracket.bracket)
>>> res_root.x
2.0945514815423265

Die endgültige Klammer ist nur wenige ULPs breit, daher kann der Fehler zwischen diesem Wert und der wahren Wurzel innerhalb von in doppelter Präzision darstellbaren Werten nicht viel kleiner sein.

>>> import numpy as np
>>> xl, xr = res_root.bracket
>>> (xr - xl) / np.spacing(xl)
2.0
>>> res_root.f_bracket
(-8.881784197001252e-16, 9.769962616701378e-15)

bracket_root und find_root akzeptieren für die meisten Argumente Arrays. Um beispielsweise die Wurzel für einige Werte des Parameters c gleichzeitig zu finden

>>> c = np.asarray([3, 4, 5])
>>> res_bracket = elementwise.bracket_root(f, 0, args=(c,))
>>> res_bracket.bracket
(array([1., 1., 2.]), array([2., 2., 4.]))
>>> res_root = elementwise.find_root(f, res_bracket.bracket, args=(c,))
>>> res_root.x
array([1.8932892 , 2.        , 2.09455148])