2012-03-26 58 views
47

Làm thế nào để tính toán đạo hàm của một hàm, ví dụLàm cách nào để tính toán đạo hàm bằng Numpy?

y = x +1

sử dụng numpy?

Giả sử, tôi muốn giá trị của đạo hàm tại x = 5 ...

+3

Bạn cần phải sử dụng Sympy: http://sympy.org/en/index.html NumPy là một tính toán số thư viện cho Python – prrao

+0

Ngoài ra, bạn có muốn phương pháp ước tính giá trị số của đạo hàm không? Đối với điều này, bạn có thể sử dụng một phương pháp khác biệt hữu hạn, nhưng nhớ rằng chúng có xu hướng ồn ào khủng khiếp. –

Trả lời

88

Bạn có bốn lựa chọn

  1. Bạn có thể sử dụng Finite Differences
  2. Bạn có thể sử dụng Automatic Derivatives
  3. Bạn có thể sử dụng Symbolic Differentiation
  4. Bạn có thể tính toán các dẫn xuất của tay.

Sự khác biệt hữu hạn không yêu cầu công cụ bên ngoài nhưng dễ bị lỗi số và nếu bạn ở trong tình huống đa biến, có thể mất một lúc.

Sự khác biệt tượng trưng là lý tưởng nếu vấn đề của bạn đủ đơn giản. Các phương pháp tượng trưng ngày càng trở nên mạnh mẽ. SymPy là một dự án tuyệt vời cho điều này tích hợp tốt với NumPy. Nhìn vào các chức năng autowrap hoặc lambdify hoặc kiểm tra Jensen's blogpost about a similar question.

Các dẫn xuất tự động rất mát mẻ, không dễ bị lỗi số, nhưng yêu cầu một số thư viện bổ sung (google cho điều này, có một vài tùy chọn tốt). Đây là lựa chọn mạnh mẽ nhất nhưng cũng phức tạp nhất/khó thiết lập. Nếu bạn có thể hạn chế mình với cú pháp numpy thì Theano có thể là một lựa chọn tốt.

Dưới đây là một ví dụ sử dụng 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.] 
+0

Xin lỗi, nếu điều này có vẻ ngu ngốc, sự khác biệt giữa 3 là gì.Phân biệt biểu tượng và 4.by phân biệt tay ?? – DrStrangeLove

+8

Khi tôi nói "sự khác biệt mang tính biểu tượng", tôi muốn ngụ ý rằng quá trình này được xử lý bởi một máy tính. Về nguyên tắc 3 và 4 chỉ khác nhau bởi ai thực hiện công việc, máy tính hoặc lập trình viên. 3 được ưu tiên hơn 4 do tính nhất quán, khả năng mở rộng và độ lười. 4 là cần thiết nếu 3 không tìm thấy một giải pháp. – MRocklin

+1

Cảm ơn rất nhiều !! Nhưng những gì là [2. 2. 2. 2. 2.] ở dòng cuối cùng ?? – DrStrangeLove

22

NumPy không cung cấp chức năng chung để tính toán các dẫn xuất. Nó có thể xử lý các trường hợp đơn giản đặc biệt của đa thức tuy nhiên:

>>> p = numpy.poly1d([1, 0, 1]) 
>>> print p 
    2 
1 x + 1 
>>> q = p.deriv() 
>>> print q 
2 x 
>>> q(5) 
10 

Nếu bạn muốn tính đạo hàm số, bạn có thể nhận được ngay với sử dụng thương số sai số trung tâm cho phần lớn các ứng dụng. Đối với đạo hàm tại một điểm duy nhất, công thức sẽ là một cái gì đó giống như

x = 5.0 
eps = numpy.sqrt(numpy.finfo(float).eps) * (1.0 + x) 
print (p(x + eps) - p(x - eps))/(2.0 * eps * x) 

nếu bạn có một mảng x của abscissae với một mảng tương ứng y các giá trị chức năng, bạn có thể comput xấp xỉ của các dẫn xuất với

numpy.diff(y)/numpy.diff(x) 
+2

'Tính toán các dẫn xuất số cho trường hợp tổng quát hơn là dễ dàng' - Tôi cầu xin sự khác biệt, tính toán các dẫn xuất số cho các trường hợp chung là khá khó khăn. Bạn chỉ cần chọn các chức năng độc đáo. –

+0

điều gì có nghĩa là sau >>> in p ?? (trên dòng thứ hai) – DrStrangeLove

+0

@DrStrangeLove: Đó là số mũ. Nó có nghĩa là để mô phỏng ký hiệu toán học. –

2

Tùy thuộc vào mức độ chính xác bạn yêu cầu bạn có thể làm việc nó ra cho mình, bằng cách sử dụng bằng chứng đơn giản của sự khác biệt:

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

chúng ta không thể thực sự lấy giới hạn của gradient, nhưng nó khá thú vị. Bạn phải xem ra mặc dù vì

>>> (((5+0.0000000000000001)**2+1)-((5)**2+1))/0.0000000000000001 
0.0 
18

Cách nhất thẳng về phía trước tôi có thể nghĩ đến là sử dụng numpy's gradient function:

x = numpy.linspace(0,10,1000) 
dx = x[1]-x[0] 
y = x**2 + 1 
dydx = numpy.gradient(y, dx) 

Bằng cách này, dydx sẽ được tính bằng chênh lệch trung ương và sẽ có cùng độ dài với y, không giống như numpy.diff, sử dụng các khác biệt về phía trước và sẽ trả về (n-1) vector kích thước.

+0

Điều gì xảy ra nếu dx không phải là hằng số? – weberc2

+2

@ weberc2, trong trường hợp đó, bạn nên chia một véc-tơ với nhau, nhưng xử lý các cạnh riêng biệt với các dẫn xuất về phía trước và lạc hậu theo cách thủ công. – Sparkler

+1

Hoặc bạn có thể nội suy y với hằng số dx, sau đó tính toán độ dốc. – IceArdor

3

tôi sẽ ném một phương pháp khác trên đống ...

scipy.interpolate 's nhiều splines Interpolating có khả năng cung cấp các dẫn xuất. Vì vậy, bằng cách sử dụng một tuyến tính tuyến tính (k=1), đạo hàm của spline (sử dụng phương pháp derivative()) phải tương đương với một sự khác biệt về phía trước. Tôi không hoàn toàn chắc chắn, nhưng tôi tin rằng bằng cách sử dụng một dẫn xuất khối spline sẽ được tương tự như một dẫn xuất khác biệt trung tâm vì nó sử dụng các giá trị từ trước và sau để xây dựng các spline khối.

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

Giả sử bạn muốn sử dụng numpy, bạn có thể về số tính đạo hàm của một hàm bất cứ lúc nào bằng cách sử dụng Rigorous definition:

def d_fun(x): 
    h = 1e-5 #in theory h is an infinitesimal 
    return (fun(x+h)-fun(x))/h 

Bạn cũng có thể sử dụng Symmetric derivative cho kết quả tốt hơn:

def d_fun(x): 
    h = 1e-5 
    return (fun(x+h)-fun(x-h))/(2*h) 

Sử dụng ví dụ của bạn, mã đầy đủ phải trông giống như sau:

def fun(x): 
    return x**2 + 1 

def d_fun(x): 
    h = 1e-5 
    return (fun(x+h)-fun(x-h))/(2*h) 

Bây giờ, bạn có thể số lượng tìm đạo hàm tại x=5:

In [1]: d_fun(5) 
Out[1]: 9.999999999621423 
Các vấn đề liên quan