[英]Solving nonlinear simultaneous equations using `minimize` in Python
我想用Python中的scipy.optimize.minimize
函數解決兩個聯立方程,特別是狗腿信任區域算法。 這需要我通過使用scipy.optimize.approx_fprime
指定問題的雅可比行列式,如我在其他帖子的一個解決方案中所建議的那樣。
我的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優化函數,所以請你解釋一下有什么問題以及如何糾正代碼?
對於最小化,您的函數應返回一個整數。 你正在返回一個元組,所以這就是問題所在。 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
為了求解方程組,您的目標是最小化左側的平方和。 為此,您可能最好使用least_squares
而不是更一般的minimize
。 文檔中有一個示例, https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.least_squares.html
在引擎蓋下,它使用信任區域類型方法。
您可以重寫函數以一次一個地生成兩個元素,而不是返回元組。 一個解決方案將在第一次,第三次,......,奇數次返回; 另一個解決方案每時每刻都會返回。 然后,您可以編寫一個最小化的新函數; 這個新函數將初始化2個列表(均衡+賠率),使用每個列表的每個其他生成元素。 這個新函數將針對兩個解決方案返回某種類型的錯誤度量,使其最小化產生最佳的2個解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.