There was a phenomenal answer posted by alko for computing a partial derivative of a multivariate function numerically in this thread.
I have a follow-up question now about enhancing this function to accept an array of input values. I have some code where I'm looping through a big long list of n-dimensional points, calculating the partial derivatives with respect to each variable, and this becomes quite computationally expensive.
It's easy enough to vectorize the function in question with np.vectorize
, but it causes issues with the partial_derivative
wrapper:
from scipy.misc import derivative
import numpy as np
def foo(x, y):
return(x**2 + y**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)
vfoo = np.vectorize(foo)
>>>foo(3,1)
>>>10
>>>vfoo([3,3], [1,1])
>>>array([10,10])
>>>partial_derivative(foo,0,[3,1])
>>>6.0
>>>partial_derivative(vfoo,0,[[3,3], [1,1]])
>>>TypeError: can only concatenate list (not "float") to list
The last line should ideally return [6.0, 6.0]
. In this case the two arrays supplied to the vectorized function vfoo
are essentially zipped up pairwise, so ([3,3], [1,1])
gets transformed into two points, [3,1]
and [3,1]
. This seems to get mangled when it gets passed to the function wraps
. The point that it ends up passing to the function derivative
is [3,3]
. In addition, there's obviously the TypeError
thrown up.
Does anyone have any recommendations or suggestions? Has anyone ever had a need to do something similar?
Edit
Sometimes I think posting on SO is just what it takes to break a mental block. I think I've got it working for anyone who might be interested:
vfoo = np.vectorize(foo)
foo(3,1)
X = np.array([3,3])
Y = np.array([1,1])
vfoo(X, Y)
partial_derivative(foo,0,[3,1])
partial_derivative(vfoo,0,[X, Y])
And the last line now returns array([ 6., 6.])