Numpy를 사용하여 미분을 어떻게 계산합니까?
예를 들어 함수의 미분을 어떻게 계산합니까?
y = x 2 +1
사용 numpy
?
x = 5에서 도함수 값을 원한다고 가정 해 보겠습니다.
네 가지 옵션이 있습니다
유한 차분에는 외부 도구가 필요하지 않지만 수치 오류가 발생하기 쉽고 다 변수 상황에있는 경우 시간이 걸릴 수 있습니다.
문제가 충분히 단순한 경우 상징적 차별화가 이상적입니다. 상징적 방법은 요즘 상당히 강력 해지고 있습니다. SymPy 는 NumPy와 잘 통합되는 훌륭한 프로젝트입니다. autowrap 또는 lambdify 함수를 보거나 비슷한 질문에 대한 Jensen의 블로그 게시물을 확인하십시오 .
자동 도함수는 매우 멋지고 숫자 오류가 발생하기 쉽지 않지만 몇 가지 추가 라이브러리가 필요합니다 (Google에서는 몇 가지 좋은 옵션이 있습니다). 이것은 가장 견고하지만 가장 정교하고 설정하기 어려운 선택입니다. 자신을 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.]
내가 생각할 수있는 가장 간단한 방법은 numpy의 그래디언트 함수를 사용하는 것입니다 .
x = numpy.linspace(0,10,1000)
dx = x[1]-x[0]
y = x**2 + 1
dydx = numpy.gradient(y, dx)
이런 식으로 dydx는 중심 차이를 사용하여 계산되며 순방향 차이를 사용하고 (n-1) 크기 벡터를 반환하는 numpy.diff와 달리 y와 길이가 같습니다.
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)
을 사용하고 싶다고 가정하면 Rigorous 정의를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
's many interpolating splines are capable of providing derivatives. So, using a linear spline (k=1
), the derivative of the spline (using the derivative()
method) should be equivalent to a forward difference. I'm not entirely sure, but I believe using a cubic spline derivative would be similar to a centered difference derivative since it uses values from before and after to construct the cubic spline.
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)
Depending on the level of precision you require you can work it out yourself, using the simple proof of differentiation:
>>> (((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
we can't actually take the limit of the gradient, but its kinda fun. You gotta watch out though because
>>> (((5+0.0000000000000001)**2+1)-((5)**2+1))/0.0000000000000001
0.0
To calculate gradients, the machine learning community uses Autograd:
To install:
pip install autograd
Here is an example:
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))
It can also compute gradients of complex functions, e.g. multivariate functions.
참고URL : https://stackoverflow.com/questions/9876290/how-do-i-compute-derivative-using-numpy
'Development Tip' 카테고리의 다른 글
SQLAlchemy : 세션 생성 vs. 재사용 (0) | 2020.10.06 |
---|---|
상속을 통해 열거 형 확장 (0) | 2020.10.06 |
mvc3의 razor에서 LabelFor의 표시 이름을 변경하는 방법은 무엇입니까? (0) | 2020.10.06 |
jQuery없이 가장 가까운 요소 찾기 (0) | 2020.10.06 |
생성자에서 정적 최종 필드 초기화 (0) | 2020.10.06 |