Как вычислить производную, используя Numpy?

Как вычислить производную функции, например

  

y = x 2 +1

используя numpy?

Допустим, я хочу получить значение производной при x = 5 ...

65 голосов | спросил DrStrangeLove 26 MarpmMon, 26 Mar 2012 20:50:34 +04002012-03-26T20:50:34+04:0008 2012, 20:50:34

7 ответов


0

У вас есть четыре варианта

  1. Вы можете использовать Конечные различия
  2. Вы можете использовать автоматические производные
  3. Вы можете использовать символьную дифференциацию
  4. Вы можете вычислить производные вручную.

Для конечных разностей не требуются внешние инструменты, но они подвержены числовым ошибкам и, если вы находитесь в многомерной ситуации, могут занять некоторое время.

Символическая дифференциация идеальна, если ваша задача достаточно проста. Символические методы становятся достаточно надежными в наши дни. SymPy - отличный проект для этого, который хорошо интегрируется с NumPy. Посмотрите на функции autowrap или lambdify или посмотрите пост в блоге Дженсена о похожем вопросе .

Автоматические производные очень крутые, не склонны к числовым ошибкам, но требуют некоторых дополнительных библиотек (для этого есть несколько хороших вариантов). Это самый надежный, но и самый сложный /сложный в настройке выбор. Если вы хорошо ограничиваетесь синтаксисом 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.]
ответил MRocklin 26 MarpmMon, 26 Mar 2012 22:02:41 +04002012-03-26T22:02:41+04:0010 2012, 22:02:41
0

Самый простой способ, который я могу придумать, - это использовать функцию градиента 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) вектор размера.

ответил Sparkler 25 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 25 Sep 2014 19:25:22 +0400 2014, 19:25:22
0

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)
ответил Sven Marnach 26 MarpmMon, 26 Mar 2012 21:09:57 +04002012-03-26T21:09:57+04:0009 2012, 21:09:57
0

Предполагая, что вы хотите использовать 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
ответил yellow01 26 Maypm17 2017, 18:47:07
0

Я добавлю другой метод в кучу ...

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)
ответил flutefreak7 4 32015vEurope/Moscow11bEurope/MoscowWed, 04 Nov 2015 22:09:29 +0300 2015, 22:09:29
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
ответил fraxel 26 MarpmMon, 26 Mar 2012 21:26:32 +04002012-03-26T21:26:32+04:0009 2012, 21:26:32
0

Для расчета градиентов сообщество машинного обучения использует Autograd:

  

" Эффективно вычисляет производные кода Numpy. "

Для установки:

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))

Он также может вычислять градиенты сложных функций, например, многомерные функции.

ответил Gordon Schücker 2 J000000Monday18 2018, 00:50:52

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132