2

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?

Wrzlprmft
  • 4,234
  • 1
  • 28
  • 54

1 Answers1

4

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)
audiodude
  • 1,865
  • 16
  • 22
  • 3
    Thanks! This worked. I also discovered that adding brackets around the variable in lambdify also works, such as: `gradFunc = sym.lambdify([x], g, modules="numpy")` – David Neiferd Jan 07 '16 at 22:38
  • @JohnnyNeiferd: Adding brackets around `x` should do nothing, because `lambdify` takes iterables of symbols or a single symbol as input. Testing it confirms this, i.e., the brackets do not solve your problem. – Wrzlprmft Apr 22 '16 at 16:14
  • 1
    I tried with brackets and it seems to work with python 3.6.5 and sympy 1.1.1 – Hyperplane May 29 '18 at 07:55