scipy.misc.derivative для функции с несколькими аргументами

Несложно вычислить частные производные функции в точке относительно первого аргумента, используя функцию SciPy scipy.misc.derivative. Вот пример:

def foo(x, y):
  return(x**2 + y**3)

from scipy.misc import derivative
derivative(foo, 1, dx = 1e-6, args = (3, ))

Но как мне взять производную функции foo по второму аргументу? Один из способов, который я могу придумать, — создать лямбда-функцию, которая изменяет аргументы вокруг, но это может быстро стать громоздким.

Кроме того, есть ли способ создать массив частных производных по некоторым или всем аргументам функции?


person tchakravarty    schedule 20.12.2013    source источник
comment
какова роль аргументов в функции производной ()?   -  person laszlopanaflex    schedule 30.08.2018


Ответы (3)


Я бы написал простую обертку, что-то вроде строк

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)

Демо:

>>> partial_derivative(foo, 0, [3,1])
6.0000000008386678
>>> partial_derivative(foo, 1, [3,1])
2.9999999995311555
person alko    schedule 20.12.2013
comment
Это хорошо, и я могу собрать их вместе как вектор частных производных, но я бы подумал, что между SciPy и SymPy один из них реализует это. Я искал функциональность, предоставляемую функцией R deriv. - person tchakravarty; 21.12.2013
comment
@fgnu плохо знаком с R, можете ли вы дать ссылку на документы для deriv - person alko; 21.12.2013
comment
Пожалуйста. Чтобы процитировать руководство, он возвращает вызов для вычисления expr и его (частных) производных одновременно. - person tchakravarty; 21.12.2013

Да, это реализовано в sympy. Демо:

>>> from sympy import symbols, diff
>>> x, y = symbols('x y', real=True)
>>> diff( x**2 + y**3, y)
3*y**2
>>> diff( x**2 + y**3, y).subs({x:3, y:1})
3
person eseprimo    schedule 07.04.2014

Вот ответ для численного дифференцирования с использованием numdifftools.

import numpy as np
import numdifftools as nd

def partial_function(f___,input,pos,value):
    tmp  = input[pos]
    input[pos] = value
    ret = f___(*input)
    input[pos] = tmp
    return ret

def partial_derivative(f,input):
    ret = np.empty(len(input))
    for i in range(len(input)):
        fg = lambda x:partial_function(f,input,i,x)
        ret[i] = nd.Derivative(fg)(input[i])
    return ret

Затем:

print (partial_derivative(lambda x,y: x*x*x+y*y,np.array([1.0,1.0])))

Дает:

[ 3.  2.]
person ntg    schedule 04.08.2015