使用sympy lambdify和scipy进行Python优化 [英] Python optimization using sympy lambdify and scipy

查看:496
本文介绍了使用sympy lambdify和scipy进行Python优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试最大化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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆