我试图理解以下代码如何工作以数值逼近多变量函数的偏导数。引用这本书:
当f是许多变量的函数时,它有多个偏导数,每个偏导数表示当我们在一个输入变量中进行小的改变时f的变化。 我们通过将它作为第i个变量的函数来计算它的第i个偏导数, 保持其他变量固定:
def partial_difference_quotient(f, v, i, h):
"""compute the ith partial difference quotient of f at v"""
w = [v_j + (h if j == i else 0) for j, v_j in enumerate(v)] # add h to just the ith element of v
return (f(w) - f(v)) / h
def estimate_gradient(f, v, h=0.00001):
return [partial_difference_quotient(f, v, i, h) for i, _ in enumerate(v)]
不幸的是,这些书并没有给出如何使用代码的任何例子;它只是声明这将给你偏导数然后继续前进。
我做的第一件事就是尝试重写代码,这样对于有背景的人来说它更具可读性(我更习惯于看C ++代码),但我不确定我是不是#39;做得对。
def partial_difference_quotient1(f, v, i, h): # i is the variable that this function is being differentiated with respect to
w = []
for j, v_j in enumerate(v):
if i == j: # add h to just the ith element of v
w.append(v_j + h)
else:
w.append(v_j)
return (f(w) - f(v)) / h
def estimate_gradient1(f, v, h=0.00001):
list1 = []
for i, _ in enumerate(v):
list1.append(partial_difference_quotient1(f, v, i, h))
return list1
如果代码正确,那么我仍然不确定如何使用它。例如,让我说我想在y = 3时找到f = x ^ 2 + x * y ^ 2的偏导数,然后我试了
def f1(x, y):
return (x*x) + (x*y*y)
v = range(-10,10)
f = partial(f1, y=3)
f_x = estimate_gradient1(f, v, h=0.00001)
我可以看到这不会起作用,因为对于isntance,你不能将列表(即v)与自身相乘(函数f1中的x * x)。但是从代码中可以清楚地看出v应该是一个列表,所以我已经知道如何使用代码。
答案 0 :(得分:3)
通常,你可以计算出矢量的部分,你可以这样做:
对于d/dx x^2+2x+1
,最简单的方法是根据y
数组计算x
的渐变:
from numpy import arange, gradient
x = arange(0, 50, 0.01) # Range
y = ((x**2) + (2*x)) + 1 # Function
ddx = gradient(y) # Gradient
dx/dt
,d2/dy2
的另一个任意示例和阶段图如下:
from scipy.integrate import odeint
from numpy import arange, sin, cos, gradient
def sdot(y, t, *args):
val = sin(t*2)+(sin(y**(t/4)))
return val
init = 0
x = arange(0, 30, 0.01)
args = (None)
dydt = odeint(sdot, y0=init, t=x, args=(args,))
d2dy2 = gradient(dydt[:, 0])
有关gradient
的其他信息,请参阅文档here,odeint
请参阅here。此外,您可能会发现有关vectorisation(也称为阵列编程)的一些其他信息也很有用。
对于实际的偏导数(即通过积分),您也可以这样做:
from scipy.misc import derivative
def partial_derivative(func, var=0, point=[]):
args = point[:]
def wraps(x):
args[var] = x
return func(*args)
return derivative(wraps, point[var], dx = 1e-6)
虽然对于不是硬核(Python)程序员的人来说这会更具挑战性。但是如果你热衷于学习它,你可以找到文件here;并在here中的Code Ship的这个精彩教程中了解有关包装器和装饰器的更多信息。
希望这能让您了解如何在Python中处理衍生产品。
答案 1 :(得分:0)
以下是如何使用它:
def f(v):
x, y = v
return (x*x) + (x*y*y)
x = 3
y = 3
v = [x, y]
grad = estimate_gradient1(f, v, h=0.00001)
print(grad)
输出:
[15.000009999965867, 18.000030000564493]
大致正确。