用Python中的“最小化”求解非线性联立方程

时间:2016-12-07 12:37:01

标签: python numpy optimization scipy

我想在Python中使用scipy.optimize.minimize函数解决两个联立方程,特别是dog-leg trust-region算法。这需要我按scipy.optimize.approx_fprime中的建议使用one solution to my other post指定问题的雅可比行列式。

我的MWE是:

import numpy as np
from scipy.integrate import quad
from scipy.optimize import minimize,approx_fprime

def myfunc(guess,a,b,c,d):

    # initial guesses
    x0 = guess[0]
    x1 = guess[1]

    # functions
    z0 = lambda x: c*np.sqrt(a**3*x0)*np.sin(x)/x0**b
    z1 = lambda x: np.cos(b*x0*x)/x1**a

    # numerical integration with 'quad'
    z0int = quad(z0,-200,200,epsabs=1e-8,epsrel=1e-6)[0] - 3.2*d
    z1int = quad(z1,-200,200,epsabs=1e-8,epsrel=1e-6)[0] + c

    return (z0int,z1int)

# constants
a = 0.2
b = 1.1
c = 2.5
d = 0.9

guess = np.array([0.3,0.02]) # initial guesses

myJac = approx_fprime(guess,myfunc,1e-9,a,b,c,d) # Jacobian

# minimisation, want to find x0 such that z0int=0 and z1int=0
xopt = minimize(myfunc,guess,args=(a,b,c,d),method='dogleg',jac=myJac)

print(xopt)

但是我收到错误TypeError: unsupported operand type(s) for -: 'tuple' and 'tuple'。我对Python优化功能并不熟悉,所以能否解释一下有什么问题以及如何纠正代码?

3 个答案:

答案 0 :(得分:0)

对于最小化,您的函数应返回一个整数。你正在返回一个元组,所以这就是问题所在。 minimize函数检查新值是否低于旧值(因此减去),但它想要减去元组而不是整数。

将代码更改为仅从要最小化的函数返回单个整数

根据评论编辑

def myfunc(guess,a,b,c,d):

    # initial guesses
    x0 = guess[0]
    x1 = guess[1]

    # functions
    z0 = lambda x: c*np.sqrt(a**3*x0)/x0**b
    z1 = lambda x: np.cos(b*x0)/x1**a

    # numerical integration with 'quad'
    z0int = quad(z0,-200,200,epsabs=1e-8,epsrel=1e-6)[0] - 3.2*d
    z1int = quad(z1,-200,200,epsabs=1e-8,epsrel=1e-6)[0] + c

    return (z0int,z1int) # <-- This should only return 1 single integer

答案 1 :(得分:0)

为了求解方程组,您的目标是最小化左侧的平方和。为此,您可能最好使用least_squares而不是更一般的minimize。文档中有一个示例https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.least_squares.html

在幕后,它使用信任区域类型方法。

答案 2 :(得分:0)

您可以重写函数以一次一个地生成两个元素,而不是返回元组。一个解决方案将在第一次,第三次,......,奇数次返回;另一个解决方案每时每刻都会返回。然后,您可以编写一个最小化的新函数;这个新函数将初始化2个列表(均衡+赔率),使用每个列表的每个其他生成元素。这个新函数将针对两个解决方案返回某种类型的错误度量,使其最小化产生最佳的2个解决方案。