Wie berechne ich zum Beispiel die Ableitung einer Funktion?
y = x 2 +1
mit numpy
?
Angenommen, ich möchte den Wert der Ableitung bei x = 5 ...
Wie berechne ich zum Beispiel die Ableitung einer Funktion?
y = x 2 +1
mit numpy
?
Angenommen, ich möchte den Wert der Ableitung bei x = 5 ...
Antworten:
Sie haben vier Möglichkeiten
Endliche Unterschiede erfordern keine externen Tools, sind jedoch anfällig für numerische Fehler und können in einer multivariaten Situation eine Weile dauern.
Die symbolische Differenzierung ist ideal, wenn Ihr Problem einfach genug ist. Symbolische Methoden werden heutzutage ziemlich robust. SymPy ist hierfür ein hervorragendes Projekt, das sich gut in NumPy integrieren lässt. Schauen Sie sich die Autowrap- oder Lambdify-Funktionen an oder lesen Sie Jensens Blogpost über eine ähnliche Frage .
Automatische Ableitungen sind sehr cool, nicht anfällig für numerische Fehler, erfordern jedoch einige zusätzliche Bibliotheken (Google gibt dafür einige gute Optionen). Dies ist die robusteste, aber auch die raffinierteste / am schwierigsten einzurichtende Wahl. Wenn Sie sich auf die numpy
Syntax beschränken möchten, ist Theano möglicherweise eine gute Wahl.
Hier ist ein Beispiel mit SymPy
In [1]: from sympy import *
In [2]: import numpy as np
In [3]: x = Symbol('x')
In [4]: y = x**2 + 1
In [5]: yprime = y.diff(x)
In [6]: yprime
Out[6]: 2⋅x
In [7]: f = lambdify(x, yprime, 'numpy')
In [8]: f(np.ones(5))
Out[8]: [ 2. 2. 2. 2. 2.]
mpmath
(nicht sicher, aber was genau sie tun).
Der einfachste Weg, den ich mir vorstellen kann, ist die Verwendung der Gradientenfunktion von numpy :
x = numpy.linspace(0,10,1000)
dx = x[1]-x[0]
y = x**2 + 1
dydx = numpy.gradient(y, dx)
Auf diese Weise wird dydx unter Verwendung zentraler Differenzen berechnet und hat die gleiche Länge wie y, im Gegensatz zu numpy.diff, das Vorwärtsdifferenzen verwendet und einen Größenvektor (n-1) zurückgibt.
dx
an numpy.gradient
statt x
? (ii) Können wir auch Ihre letzte Zeile wie folgt machen : dydx = numpy.gradient(y, numpy.gradient(x))
?
NumPy bietet keine allgemeine Funktionalität zum Berechnen von Derivaten. Es kann jedoch den einfachen Spezialfall von Polynomen behandeln:
>>> p = numpy.poly1d([1, 0, 1])
>>> print p
2
1 x + 1
>>> q = p.deriv()
>>> print q
2 x
>>> q(5)
10
Wenn Sie die Ableitung numerisch berechnen möchten, können Sie für die überwiegende Mehrheit der Anwendungen die Verwendung zentraler Differenzquotienten vermeiden. Für die Ableitung in einem einzelnen Punkt wäre die Formel ungefähr so
x = 5.0
eps = numpy.sqrt(numpy.finfo(float).eps) * (1.0 + x)
print (p(x + eps) - p(x - eps)) / (2.0 * eps * x)
Wenn Sie ein Array x
von Abszissen mit einem entsprechenden Array y
von Funktionswerten haben, können Sie Approximationen von Ableitungen mit berechnen
numpy.diff(y) / numpy.diff(x)
1 * x**2 + 1
. Sie setzen das 2
in die obige Zeile, weil es ein Exponent ist. Schau es dir aus der Ferne an.
Angenommen, Sie möchten verwenden numpy
, können Sie die Ableitung einer Funktion an jedem Punkt mithilfe der rigorosen Definition numerisch berechnen :
def d_fun(x):
h = 1e-5 #in theory h is an infinitesimal
return (fun(x+h)-fun(x))/h
Sie können auch die symmetrische Ableitung verwenden, um bessere Ergebnisse zu erzielen:
def d_fun(x):
h = 1e-5
return (fun(x+h)-fun(x-h))/(2*h)
In Ihrem Beispiel sollte der vollständige Code ungefähr so aussehen:
def fun(x):
return x**2 + 1
def d_fun(x):
h = 1e-5
return (fun(x+h)-fun(x-h))/(2*h)
Jetzt können Sie die Ableitung numerisch finden unter x=5
:
In [1]: d_fun(5)
Out[1]: 9.999999999621423
Ich werde eine andere Methode auf den Stapel werfen ...
scipy.interpolate
Die vielen interpolierenden Splines können Ableitungen bereitstellen. Bei Verwendung eines linearen Splines ( k=1
) sollte die Ableitung des Splines (unter Verwendung der derivative()
Methode) einer Vorwärtsdifferenz entsprechen. Ich bin nicht ganz sicher, aber ich glaube, dass die Verwendung einer kubischen Spline-Ableitung einer zentrierten Differenzableitung ähnlich wäre, da sie Werte von vorher und nachher verwendet, um den kubischen Spline zu konstruieren.
from scipy.interpolate import InterpolatedUnivariateSpline
# Get a function that evaluates the linear spline at any x
f = InterpolatedUnivariateSpline(x, y, k=1)
# Get a function that evaluates the derivative of the linear spline at any x
dfdx = f.derivative()
# Evaluate the derivative dydx at each x location...
dydx = dfdx(x)
Zur Berechnung von Verläufen verwendet die Community für maschinelles Lernen Autograd:
Installieren:
pip install autograd
Hier ist ein Beispiel:
import autograd.numpy as np
from autograd import grad
def fct(x):
y = x**2+1
return y
grad_fct = grad(fct)
print(grad_fct(1.0))
Es kann auch Gradienten komplexer Funktionen berechnen, z. B. multivariate Funktionen.
Abhängig von der Präzision, die Sie benötigen, können Sie dies anhand des einfachen Differenzierungsnachweises selbst herausfinden:
>>> (((5 + 0.1) ** 2 + 1) - ((5) ** 2 + 1)) / 0.1
10.09999999999998
>>> (((5 + 0.01) ** 2 + 1) - ((5) ** 2 + 1)) / 0.01
10.009999999999764
>>> (((5 + 0.0000000001) ** 2 + 1) - ((5) ** 2 + 1)) / 0.0000000001
10.00000082740371
Wir können die Grenze des Gefälles nicht wirklich überschreiten, aber es macht irgendwie Spaß. Du musst aber aufpassen, weil
>>> (((5+0.0000000000000001)**2+1)-((5)**2+1))/0.0000000000000001
0.0
Sie können verwenden scipy
, was ziemlich einfach ist:
scipy.misc.derivative(func, x0, dx=1.0, n=1, args=(), order=3)
Finden Sie die n-te Ableitung einer Funktion an einem Punkt.
In deinem Fall:
from scipy.misc import derivative
def f(x):
return x**2 + 1
derivative(f, 5, dx=1e-6)
# 10.00000000139778