Як я можу обчислити похідну функції, наприклад
y = x 2 +1
використання numpy
?
Скажімо, я хочу значення похідної при x = 5 ...
Як я можу обчислити похідну функції, наприклад
y = x 2 +1
використання numpy
?
Скажімо, я хочу значення похідної при x = 5 ...
Відповіді:
У вас є чотири варіанти
Кінцеві відмінності не вимагають зовнішніх інструментів, але вони схильні до чисельних помилок, і, якщо ви перебуваєте в багатовимірній ситуації, це може зайняти деякий час.
Символічна диференціація ідеальна, якщо ваша проблема досить проста. Символічні методи в наш час стають досить надійними. SymPy - чудовий проект для цього, який добре інтегрується з NumPy. Подивіться на функції автоматичного обертання або лямбдіфікації або перегляньте допис блогу Дженсена про подібне питання .
Автоматичні похідні дуже класні, не схильні до числових помилок, але вимагають додаткових бібліотек (для цього потрібно погуглити, є кілька хороших варіантів). Це найнадійніший, але також найскладніший / складний у налаштуванні вибір. Якщо ви добре обмежуєтесь numpy
синтаксисом, то Theano може бути хорошим вибором.
Ось приклад використання 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
(однак не впевнений, що саме вони роблять).
Найбільш прямий спосіб, про який я можу придумати, - це використання функції градієнта Numpy :
x = numpy.linspace(0,10,1000)
dx = x[1]-x[0]
y = x**2 + 1
dydx = numpy.gradient(y, dx)
Таким чином, dydx буде обчислюватися з використанням центральних різниць і матиме однакову довжину як y, на відміну від numpy.diff, який використовує прямі різниці і повертає (n-1) вектор розміру.
dx
до numpy.gradient
замість x
? (ii) Чи можемо ми також зробити останній ваш рядок таким чином dydx = numpy.gradient(y, numpy.gradient(x))
:?
NumPy не надає загальної функціональності для обчислення похідних. Однак він може обробляти простий особливий випадок поліномів:
>>> p = numpy.poly1d([1, 0, 1])
>>> print p
2
1 x + 1
>>> q = p.deriv()
>>> print q
2 x
>>> q(5)
10
Якщо ви хочете обчислити похідну чисельно, ви можете уникнути, використовуючи коефіцієнти центральної різниці для переважної більшості програм. Для похідної в одній точці формула буде приблизно такою
x = 5.0
eps = numpy.sqrt(numpy.finfo(float).eps) * (1.0 + x)
print (p(x + eps) - p(x - eps)) / (2.0 * eps * x)
якщо у вас є масив x
абсцис із відповідним масивом y
значень функції, ви можете обчислити наближення похідних з
numpy.diff(y) / numpy.diff(x)
1 * x**2 + 1
. Вони ставлять 2
у рядок вище, оскільки це показник ступеня. Подивіться на це здалеку.
Припускаючи, що ви хочете використовувати numpy
, ви можете чисельно обчислити похідну функції в будь-якій точці, використовуючи суворе визначення :
def d_fun(x):
h = 1e-5 #in theory h is an infinitesimal
return (fun(x+h)-fun(x))/h
Ви також можете використовувати симетричну похідну для кращих результатів:
def d_fun(x):
h = 1e-5
return (fun(x+h)-fun(x-h))/(2*h)
На вашому прикладі повний код повинен виглядати приблизно так:
def fun(x):
return x**2 + 1
def d_fun(x):
h = 1e-5
return (fun(x+h)-fun(x-h))/(2*h)
Тепер ви можете чисельно знайти похідну за адресою x=5
:
In [1]: d_fun(5)
Out[1]: 9.999999999621423
Я кину ще один метод на купу ...
scipy.interpolate
багато інтерполюючих сплайнів здатні надати похідні. Отже, використовуючи лінійний сплайн ( k=1
), похідна сплайна (за допомогою derivative()
методу) повинна бути еквівалентна прямій різниці. Я не зовсім впевнений, але я вважаю, що використання кубічної сплайн-похідної було б подібним до похідної відцентрованої різниці, оскільки вона використовує значення до і після для побудови кубічного сплайну.
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)
Для обчислення градієнтів спільнота машинного навчання використовує Autograd:
Щоб встановити:
pip install autograd
Ось приклад:
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))
Він також може обчислювати градієнти складних функцій, наприклад багатовимірних функцій.
Залежно від рівня точності, який вам потрібен, ви можете розробити це самостійно, використовуючи простий доказ диференціації:
>>> (((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
ми насправді не можемо взяти межу градієнта, але це якось весело. Ти мусиш пильнувати, хоча тому, що
>>> (((5+0.0000000000000001)**2+1)-((5)**2+1))/0.0000000000000001
0.0
Ви можете використовувати scipy
, що досить прямо вперед:
scipy.misc.derivative(func, x0, dx=1.0, n=1, args=(), order=3)
Знайдіть n-ту похідну функції в точці.
У вашому випадку:
from scipy.misc import derivative
def f(x):
return x**2 + 1
derivative(f, 5, dx=1e-6)
# 10.00000000139778