web-dev-qa-db-ja.com

複数の引数関数の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, ))

しかし、2番目の引数に関して関数fooの導関数をどのように取るのでしょうか?私が考えることができる1つの方法は、周りの引数を再調整するラムダ関数を生成することですが、それはすぐに面倒になる可能性があります。

また、関数の引数の一部またはすべてに関して偏導関数の配列を生成する方法はありますか?

15
tchakravarty

私は単純なラッパーを書きます。

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
14
alko

はい、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
3
eseprimo

これが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.]
0
ntg