高阶多元导数

时间:2019-07-15 08:23:55

标签: python numpy scipy scientific-computing

在Python中是否有一种打包的方法来计算高阶多元导数(使用有限差分,而不是符号计算)?

例如,如果f从R ^ 2到R计算函数cos(x)* y,即f采取形状为2的numpy数组并返回浮点数(或形状为()的数组,是否有一个函数partial使得partial([2,1])(f)计算该函数(d ^ 2 / dx ^ 2)(d / dy)f = -cos(x) * 1从R ^ 2到R,例如

np.isclose(partial([2,1])(f)(0),1.0)

默认库中有很多有限差分工具(对于“一种方法”来说太多了):

https://docs.scipy.org/doc/scipy/reference/generated/scipy.misc.derivative.html https://docs.scipy.org/doc/numpy/reference/generated/numpy.gradient.html https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.optimize.approx_fprime.html https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.misc.central_diff_weights.html https://github.com/statsmodels/statsmodels/blob/master/statsmodels/tools/numdiff.py

但是,它们都不能处理多元函数和高阶导数,即它们都不能处理上述工作。

(也有https://pypi.org/project/numdifftools/,但似乎不符合我的需要。作者没有回答我的问题。)

自己编写工具很容易。然而,似乎很难做到这一点,即以准确和稳定的方式。例如,对于小于1e-3的网格宽度,即使对于上述简单函数和仅二阶混合导数,直接递归实现也是不稳定的。

PS:我不是在要求数组的有限差分(https://docs.scipy.org/doc/numpy/reference/generated/numpy.diff.htmlhttps://github.com/maroba/findiff是这样做的)。我需要在任意点上评估导数,而无需在完整的笛卡尔网格上计算函数的值。

2 个答案:

答案 0 :(得分:0)

scipy.optimize._approx_derivative可以做到。但是,这不是公共功能,因此,如果最终使用它,您将自己承担责任。

答案 1 :(得分:0)

您可以编写包装并使用scipy.misc.derivative函数。

对于简单的x,y导数,请使用this答案

对于矢量导数,您可以定义g(t, (x, y), vector) = f((x,y) + t * vector),它会在所选矢量方向上产生g'(0, args=((x,y), vector)) =方向导数

from scipy.misc import derivative

f = lambda x: x[0] * np.cos(x[1])

def vector_derivative(f, x0, vector, delta=1):
    def wrapper(x, x0, vector):
        return f(np.asarray(x0) + x * np.asarray(vector))
    return derivative(wrapper, 0, args=(x0, vector), dx=delta)

vector_derivative(f, [1, np.pi/2], [0, 1], delta=0.01)
>> -0.9999833334166673