ฉันจะคำนวณอนุพันธ์ของฟังก์ชันได้อย่างไร
y = x 2 +1
ใช้numpy
?
สมมติว่าฉันต้องการค่าอนุพันธ์ที่ x = 5 ...
ฉันจะคำนวณอนุพันธ์ของฟังก์ชันได้อย่างไร
y = x 2 +1
ใช้numpy
?
สมมติว่าฉันต้องการค่าอนุพันธ์ที่ x = 5 ...
คำตอบ:
คุณมีสี่ตัวเลือก
ความแตกต่าง จำกัด ไม่จำเป็นต้องใช้เครื่องมือภายนอก แต่มีแนวโน้มที่จะเกิดข้อผิดพลาดทางตัวเลขและหากคุณอยู่ในสถานการณ์หลายตัวแปรอาจใช้เวลาสักครู่
การแยกแยะสัญลักษณ์เหมาะอย่างยิ่งหากปัญหาของคุณง่ายพอ วิธีการเชิงสัญลักษณ์เริ่มมีประสิทธิภาพมากในทุกวันนี้ SymPyเป็นโครงการที่ยอดเยี่ยมสำหรับสิ่งนี้ซึ่งทำงานร่วมกับ NumPy ได้เป็นอย่างดี ดู autowrap หรือ lambdify ฟังก์ชั่นหรือเช็คเอาblogpost เซ่นเกี่ยวกับคำถามที่คล้ายกัน
อนุพันธ์อัตโนมัตินั้นยอดเยี่ยมมากไม่มีแนวโน้มที่จะเกิดข้อผิดพลาดเกี่ยวกับตัวเลข แต่ต้องการไลบรารีเพิ่มเติม (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.]
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
ของ abscissae ที่มีอาร์เรย์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
Spline interpolating จำนวนมากสามารถให้อนุพันธ์ได้ ดังนั้นการใช้เส้นโค้งเชิงเส้น ( k=1
) อนุพันธ์ของเส้นโค้ง (โดยใช้derivative()
วิธีนี้) ควรเทียบเท่ากับผลต่างไปข้างหน้า ฉันไม่แน่ใจทั้งหมด แต่ฉันเชื่อว่าการใช้อนุพันธ์ลูกบาศก์ 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)
ในการคำนวณการไล่ระดับสีชุมชนแมชชีนเลิร์นนิงใช้ 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