Örneğin bir fonksiyonun türevini nasıl hesaplayabilirim?
y = x 2 +1
kullanarak numpy
?
Diyelim ki, türevin değerini x = 5'de istiyorum ...
Örneğin bir fonksiyonun türevini nasıl hesaplayabilirim?
y = x 2 +1
kullanarak numpy
?
Diyelim ki, türevin değerini x = 5'de istiyorum ...
Yanıtlar:
Dört seçeneğiniz var
Sonlu farklılıklar harici araçlar gerektirmez, ancak sayısal hataya eğilimlidir ve çok değişkenli bir durumdaysanız, biraz zaman alabilir.
Sorununuz yeterince basitse, sembolik farklılaştırma idealdir. Sembolik yöntemler bu günlerde oldukça sağlamlaşıyor. SymPy bunun için NumPy ile iyi bütünleşen mükemmel bir projedir. Otomatik sarma veya lambdify işlevlerine bakın veya Jensen'in benzer bir soru hakkındaki blog yayınına bakın .
Otomatik türevler çok iyidir, sayısal hatalara yatkın değildir, ancak bazı ek kitaplıklar gerektirir (bunun için google, birkaç iyi seçenek vardır). Bu en sağlam ama aynı zamanda en karmaşık / kurulumu zor olan seçenektir. Kendinizi numpy
sözdizimiyle sınırlamakta iyiyseniz , Theano iyi bir seçim olabilir.
İşte SymPy'yi kullanan bir örnek
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
(tam olarak ne yaptıklarından emin değilim).
Aklıma gelen en basit yol, numpy'nin gradyan fonksiyonunu kullanmak :
x = numpy.linspace(0,10,1000)
dx = x[1]-x[0]
y = x**2 + 1
dydx = numpy.gradient(y, dx)
Bu şekilde, dydx, merkezi farklar kullanılarak hesaplanacak ve ileri farkları kullanan ve (n-1) boyut vektörünü döndürecek olan numpy.diff'in aksine, y ile aynı uzunluğa sahip olacaktır.
dx
için numpy.gradient
yerine x
? aşağıdaki gibi (ii) biz de senin son satırı yapabilir: dydx = numpy.gradient(y, numpy.gradient(x))
?
NumPy, türevleri hesaplamak için genel işlevsellik sağlamaz. Polinomların basit ve özel durumunu ele alabilir ancak:
>>> p = numpy.poly1d([1, 0, 1])
>>> print p
2
1 x + 1
>>> q = p.deriv()
>>> print q
2 x
>>> q(5)
10
Türevi sayısal olarak hesaplamak istiyorsanız, uygulamaların büyük çoğunluğu için merkezi fark katsayılarını kullanmaktan kurtulabilirsiniz. Tek bir noktadaki türev için formül şöyle bir şey olacaktır:
x = 5.0
eps = numpy.sqrt(numpy.finfo(float).eps) * (1.0 + x)
print (p(x + eps) - p(x - eps)) / (2.0 * eps * x)
Eğer x
karşılık gelen y
fonksiyon değerleri dizisine sahip bir apsis dizisine sahipseniz, türevlerin yaklaşık değerlerini şu şekilde hesaplayabilirsiniz:
numpy.diff(y) / numpy.diff(x)
1 * x**2 + 1
. 2
Üstteki satıra koydular çünkü bu bir üs. Uzaktan bak.
numpy
Kullanmak istediğinizi varsayarsak , Titiz tanımını kullanarak herhangi bir noktada bir fonksiyonun türevini sayısal olarak hesaplayabilirsiniz :
def d_fun(x):
h = 1e-5 #in theory h is an infinitesimal
return (fun(x+h)-fun(x))/h
Daha iyi sonuçlar için Simetrik türevi de kullanabilirsiniz :
def d_fun(x):
h = 1e-5
return (fun(x+h)-fun(x-h))/(2*h)
Örneğinizi kullanırsanız, tam kod aşağıdaki gibi görünmelidir:
def fun(x):
return x**2 + 1
def d_fun(x):
h = 1e-5
return (fun(x+h)-fun(x-h))/(2*h)
Şimdi türevi sayısal olarak şu adreste bulabilirsiniz x=5
:
In [1]: d_fun(5)
Out[1]: 9.999999999621423
Yığın üzerine başka bir yöntem atacağım ...
scipy.interpolate
birçok enterpolasyonlu spline türevler sağlayabilir. Dolayısıyla, doğrusal bir spline ( k=1
) kullanarak, spline'ın türevi ( derivative()
yöntemi kullanarak ) bir ileri farka eşdeğer olmalıdır. Tam olarak emin değilim, ancak kübik spline'ı oluşturmak için önceki ve sonraki değerleri kullandığı için kübik spline türevi kullanmanın ortalanmış bir fark türevine benzer olacağına inanıyorum.
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)
Gradyanları hesaplamak için makine öğrenimi topluluğu Autograd'ı kullanır:
Yüklemek:
pip install autograd
İşte bir örnek:
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))
Ayrıca, karmaşık fonksiyonların gradyanlarını, örneğin çok değişkenli fonksiyonları da hesaplayabilir.
İhtiyaç duyduğunuz hassasiyet düzeyine bağlı olarak, basit farklılaştırma kanıtını kullanarak bunu kendiniz çözebilirsiniz:
>>> (((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
aslında gradyan sınırını alamayız, ama biraz eğlencelidir. Yine de dikkatli olmalısın çünkü
>>> (((5+0.0000000000000001)**2+1)-((5)**2+1))/0.0000000000000001
0.0
Kullanabilirsiniz scipy
, ki bu oldukça basittir:
scipy.misc.derivative(func, x0, dx=1.0, n=1, args=(), order=3)
Bir noktada bir fonksiyonun n inci türevini bulun.
Senin durumunda:
from scipy.misc import derivative
def f(x):
return x**2 + 1
derivative(f, 5, dx=1e-6)
# 10.00000000139778