Search code examples
pythonpython-2.7sympylambdify

How to make a Sympy lambdify(ed) function accept array input?


I’m trying to create a function in Python 2.7 that accepts a function handle and the number of variables in the function as the input and returns a new function that calculates the gradient of the input function. This is what I have so far.

import sympy as sym
import numpy as np

def getSymbolicGradient(func,numVars):
    # Initialize Some Variables
    g = numVars * [0]

    # Create All the Symbolic Variables
    x = sym.symarray('x',numVars)

    # Calculate the Gradients
    for i in range(numVars):
        g[i] = sym.diff(func(x),x[i])

    gradFunc = sym.lambdify(x, g, modules="numpy")

    return gradFunc

Say I use gradFunc with the following code:

def myVecFunc(x):
    return 2*x[0]**2 + 4*x[1] + 2

gradFunc = getSymbolicGradient(func=myVecFunc, numVars=2)

If I call it using two separate arguments it works, such as the following:

print( gradFunc(1,2) )

However, if I call it using a single argument (say a Numpy array),

print( gradFunc(np.array([1,2])) )

I get the following error:

TypeError: () takes exactly 2 arguments (1 given)

How can I get lambdify to accept the input arguments as a single array inside of individual values? Are there better (built-in) Sympy methods for generating a symbolic expression for a gradient of a function that accepts arrays as inputs?


Solution

  • I'm not too familiar with numpy, but generally in Python you can use the * operator to unpack array values.

    a = [2, 4, 6]
    my_func(*a)
    

    is logically equivalent to

    a = 2
    b = 4
    c = 6
    my_func(a, b, c)