18

It is straightforward to compute the partial derivatives of a function at a point with respect to the first argument using the SciPy function scipy.misc.derivative. Here is an example:

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

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

But how would I go about taking the derivative of the function foo with respect to the second argument? One way I can think of is to generate a lambda function that rejigs the arguments around, but that can quickly get cumbersome.

Also, is there a way to generate an array of partial derivatives with respect to some or all of the arguments of a function?

Cœur
  • 37,241
  • 25
  • 195
  • 267
tchakravarty
  • 10,736
  • 12
  • 72
  • 116

3 Answers3

22

I would write a simple wrapper, something along the lines of

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)

Demo:

>>> partial_derivative(foo, 0, [3,1])
6.0000000008386678
>>> partial_derivative(foo, 1, [3,1])
2.9999999995311555
alko
  • 46,136
  • 12
  • 94
  • 102
  • 1
    That's nice, and I can put them together as a vector of partial derivatives, but would have thought that between SciPy and SymPy, one of them would implement this. What I was looking for is the functionality provided by the R `deriv` function. – tchakravarty Dec 20 '13 at 21:37
  • @fgnu not well acquinted with R, can you link to docs for `deriv` – alko Dec 20 '13 at 21:38
  • [Here you go](http://stat.ethz.ch/R-manual/R-patched/library/stats/html/deriv.html). To quote the manual "It returns a call for computing the expr _and its (partial) derivatives, simultaneously._" – tchakravarty Dec 20 '13 at 21:39
2

Yes, it is implemented in sympy. Demo:

>>> 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
eseprimo
  • 49
  • 2
0

Here is an answer for numerical differentiation using 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

Then:

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

Gives:

[ 3.  2.]
ntg
  • 12,950
  • 7
  • 74
  • 95