As @Dair pointed out, sympy's lambdify in general requires more than one arguments, while scipy expects only one argument, a list (or an array) that contains all the values of each variable. Because my objective function is most conveniently defined using sympy, I need to find a way to get around this incompatibility of sympy and scipy.
@lhcgeneva pointed out the answer to a similar question. This answer does not conveniently handle a large number of independent variables, especially when the number of independent variables can change, requiring writing out the "vectorized" version of the objective function to be redefined. However, inspired by this post, I figured out the following solution using *tuple():
import sympy
from scipy.optimize import minimize
from sympy.utilities.lambdify import lambdify
a,b,G = sympy.symbols('a b G')
func = -1*((G - a)**2 + b)
my_func = lambdify((G,a,b), func)
def my_func_v(x):
return my_func(*tuple(x))
results = minimize(my_func_v,[0.1,0.1,0.1])
In the example I gave, it seems unnecessary to use *tuple(), but for the problem I want to solve, it saves a lot of hassle. Here's an example that is more similar to the question that I want to solve
NUM_VAR = 10
x = np.array(sympy.symbols('x0:%d'%NUM_VAR))
func = np.sum((x-1)**2)
my_func = lambdify(x, func)
def my_func_v(x):
return my_func(*tuple(x))
results = minimize(my_func_v,np.zeros(NUM_VAR))
This *tuple() thing can save me from writing out all the elements of x like the following (for the case of NUM_VAR=10):
def my_func_v(x):
return my_func(x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9])
Also, we don't need to change my_func_v when NUM_VAR changes.