在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.html和https://github.com/maroba/findiff是这样做的)。我需要在任意点上评估导数,而无需在完整的笛卡尔网格上计算函数的值。
答案 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