使用sympy lambdify和scipy进行Python优化 [英] Python optimization using sympy lambdify and scipy
问题描述
我正在尝试最大化sympy定义的功能,但无法使其正常工作.基本思想可以概括如下:
I'm trying to maximize a function defined by sympy but cannot make it work. The basic idea can be summarized as follows:
import sympy
from scipy.optimize import minimize
from sympy.utilities.lambdify import lambdify
a,b,G = sympy.symbols('a b G')
func = (G - a)**2 + b
my_func = lambdify((G,a,b), -1*func)
results = minimize(my_func,[0.1,0.1,0.1])
如果我定义一个单变量函数,该代码将起作用,但是只要我有多个变量,就会收到以下错误消息.
The code works if I define a single-variable function, but as long as I have more than one variable, I receive the following error message.
TypeError: <lambda>() takes exactly 3 arguments (1 given)
有人可以帮助我确定哪里出了问题吗?
Can someone help me to identify where went wrong?
推荐答案
正如@Dair指出的那样,sympy的lambdify通常需要多个参数,而scipy则只需要一个参数,即包含所有参数的列表(或数组)每个变量的值.因为我的目标函数最方便地使用sympy定义,所以我需要找到一种方法来解决sympy和scipy的不兼容问题.
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指出了类似问题的答案.这个答案不能方便地处理大量的自变量,特别是当自变量的数量可以更改时,这就要求写出要重新定义的目标函数的向量化"版本.但是,受本文的启发,我使用* tuple()找出了以下解决方案:
@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])
在我给出的示例中,似乎不需要使用* tuple(),但是对于我要解决的问题,它节省了很多麻烦.这是一个更类似于我要解决的问题的示例
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))
这* tuple()可以使我免于写出x的所有元素,如下所示(对于NUM_VAR = 10):
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])
此外,当NUM_VAR更改时,我们不需要更改my_func_v.
Also, we don't need to change my_func_v when NUM_VAR changes.
这篇关于使用sympy lambdify和scipy进行Python优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!