解释Python代码的多变量函数的偏导数

时间:2016-05-01 23:07:13

标签: python

我试图理解以下代码如何工作以数值逼近多变量函数的偏导数。引用这本书:

  

当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应该是一个列表,所以我已经知道如何使用代码。

2 个答案:

答案 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

产生以下结果: Plot of <code>f(x)</code> and its gradient.

dx/dtd2/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])

Plot of <code>f(x)</code>, its gradient, and its phase plot.

有关gradient的其他信息,请参阅文档hereodeint请参阅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]

大致正确。