使用scipy.optimize的fsolve,root函數(shù)求解非線性方程問(wèn)題
scipy.optimize的fsolve,root函數(shù)求解非線性方程
求解如下方程
from scipy.optimize import fsolve, root import numpy as np # 定義方程內(nèi)容 def f(x, *arg): return arg[0] * 2 ** (1 - x) / (1 - x) + (1 - arg[0]) * 1.6 ** (1 - x) / (1 - x) - arg[0] * 3.85 ** (1 - x) / ( 1 - x) - (1 - arg[0]) * 0.1 ** (1 - x) / (1 - x) # 參數(shù)p為一個(gè)超參數(shù) results = [[p * 0.1, fsolve(f, x0=0, args=(p * 0.1))[0]] for p in range(2, 10)] print(np.array(results), '\n') results = [[p * 0.1, root(f, x0=0, args=(p * 0.1))['x'][0]] for p in range(2, 10)] print(np.array(results)) # output results [[ 0.2 -0.94683705] [ 0.3 -0.48657472] [ 0.4 -0.14263228] [ 0.5 0.14636333] [ 0.6 0.4114561 ] [ 0.7 0.67618002] [ 0.8 0.9705809 ] [ 0.9 1.3683912 ]] [[ 0.2 -0.94683705] [ 0.3 -0.48657472] [ 0.4 -0.14263228] [ 0.5 0.14636333] [ 0.6 0.4114561 ] [ 0.7 0.67618002] [ 0.8 0.9705809 ] [ 0.9 1.3683912 ]]
python求解非線性方程組的幾種方式
問(wèn)題
對(duì)此非線性方程組,根據(jù)方程圖像(如下圖)可知,應(yīng)有4組不同的解。以下嘗試用不同的方法求出該方程組的解。
1. 利用gekko的GEKKO求解
"""利用gekko求解非線性方程組""" from gekko import GEKKO m = GEKKO() x = m.Var(value=0) # 給定初值為0 y = m.Var(value=0) # 給定初值為0 m.Equations([x ** 2 / 4 + y ** 2 == 1, (x - 0.2) ** 2 - y == 3]) m.solve(disp=False) x, y = x.value, y.value print(x, y)
輸出結(jié)果:
[-1.2961338938] [-0.7615833719]
換不同初值計(jì)算得到的結(jié)果如下:
[-1.6818042485] [0.54118722964] # 給定初值為(-2,0)
[1.9760411678] [0.15432222765] # 給定初值為(2,0)
[1.8018969861] [-0.43392604594] # 給定初值為(2,-2)
[1.9760412095] [0.15432236862] # 給定初值為(10,10)
[1.801896954] [-0.4339261545] # 給定初值為(10,-10)
可知,用這種方法并不能得到方程組的全部解,并且最終得到的解為其解集中與給定的初值“距離”較近的一個(gè)。
2. 利用scipy.optimize的fsolve求解
optimize庫(kù)中的fsolve函數(shù)可以用來(lái)對(duì)非線性方程組進(jìn)行求解。
from scipy.optimize import fsolve def f(X): x = X[0] y = X[1] return [x ** 2 / 4 + y ** 2 - 1, (x - 0.2) ** 2 - y - 3] X0 = [0, 0] result = fsolve(f, X0) print(result)
輸出結(jié)果:
[-1.29613389 -0.76158337]
換不同初值計(jì)算得到的結(jié)果如下:
[-1.68180425 0.54118723] # 給定初值為(-2,0)
[1.97604116 0.15432219] # 給定初值為(2,0)
[ 1.80189699 -0.43392605] # 給定初值為(2,-2)
[1.97604116 0.15432219] # 給定初值為(10,10)
[ 1.80189699 -0.43392605] # 給定初值為(10,-10)
可知,用這種方法也不能得到方程組的全部解,并且最終得到的解與給定初值有關(guān)。
3. 利用scipy.optimize的root求解
from scipy.optimize import fsolve, root def f(X): x = X[0] y = X[1] return [x ** 2 / 4 + y ** 2 - 1, (x - 0.2) ** 2 - y - 3] X0 = [10, 10] result1 = fsolve(f, X0) result2 = root(f, X0) print(result2)
輸出結(jié)果:
fjac: array([[-0.2547064 , -0.96701843],
[ 0.96701843, -0.2547064 ]])
fun: array([-3.34943184e-12, 2.75734990e-12])
message: 'The solution converged.'
nfev: 22
qtf: array([-1.65320424e-10, -2.73193431e-10])
r: array([-3.70991104, 0.8956477 , 0.56891317])
status: 1
success: True
x: array([1.97604116, 0.15432219])
結(jié)果與fsolve函數(shù)得到的結(jié)果相同。
4. 利用scipy.optimize的leastsq求解
from scipy.optimize import leastsq def f(X): x = X[0] y = X[1] return [x ** 2 / 4 + y ** 2 - 1, (x - 0.2) ** 2 - y - 3] X0 = [10, 10] h = leastsq(f, X0) print(h)
輸出結(jié)果:
(array([1.97604116, 0.15432219]), 2)
5. 利用sympy的solve和nsolve求解
5.1 利用solve求解所有精確解
from sympy import symbols, Eq, solve, nsolve x, y = symbols('x y') eqs = [Eq(x ** 2 / 4 + y ** 2, 1), Eq((x - 0.2) ** 2 - y, 3)] print(solve(eqs, [x, y]))
輸出結(jié)果:
[[-1.68180424847377 + 1.56760579250585e-32*I
0.541187229573922 - 3.01196919624356e-31*I]
[-1.29613389377477 + 1.95607066863502e-32*I
-0.761583371898353 + 3.93313832308616e-31*I]
[1.80189698634479 - 1.95607066863926e-32*I
-0.433926045139482 - 8.10475677027422e-31*I]
[1.97604115590375 - 1.56760579250161e-32*I
0.154322187463913 + 7.18358764343162e-31*I]]
可以看出,用這種方法能夠得到方程組的全部解,并且為精確解,缺點(diǎn)是求解時(shí)間較長(zhǎng)。
5.2 利用nsolve求解數(shù)值解
from sympy import symbols, Eq, nsolve x, y = symbols('x y') eqs = [Eq(x ** 2 / 4 + y ** 2, 1), Eq((x - 0.2) ** 2 - y, 3)] X0 = [3, 4] print(nsolve(eqs, [x, y], X0))
輸出結(jié)果:
Matrix([[1.97604115590375], [0.154322187463913]])
nsolve為數(shù)值求解,需要指定一個(gè)初始值,初始值會(huì)影響最終得到哪一個(gè)解(如果有多解的話),而且初始值設(shè)的不好,則可能找不到解。
scipy.optimize.root求解速度快,但只能得到靠近初始值的一個(gè)解。對(duì)形式簡(jiǎn)單、有求根公式的方程,sympy.solve能夠得到所有嚴(yán)格解,但當(dāng)方程組變量較多時(shí),它求起來(lái)會(huì)很慢。而且對(duì)于不存在求根公式的復(fù)雜方程,sympy.solve無(wú)法求解。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python 消除 futureWarning問(wèn)題的解決
今天小編就為大家分享一篇python 消除 futureWarning問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12關(guān)于python pyqt5安裝失敗問(wèn)題的解決方法
這篇文章主要給大家介紹了關(guān)于python pyqt5安裝失敗問(wèn)題的解決方法,文中給出了詳細(xì)的解決過(guò)程與解決方法,對(duì)同樣遇到這個(gè)問(wèn)題的朋友們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08Django+Bootstrap實(shí)現(xiàn)計(jì)算器的示例代碼
本文主要介紹了Django+Bootstrap實(shí)現(xiàn)計(jì)算器的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11python中in在list和dict中查找效率的對(duì)比分析
今天小編就為大家分享一篇python中in在list和dict中查找效率的對(duì)比分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05如何利用pygame實(shí)現(xiàn)簡(jiǎn)單的五子棋游戲
這篇文章主要給大家介紹了關(guān)于如何利用pygame實(shí)現(xiàn)簡(jiǎn)單的五子棋游戲的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用pygame具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12Python try-except-else-finally的具體使用
本文主要介紹了Python try-except-else-finally的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08pygame實(shí)現(xiàn)一個(gè)類似滿天星游戲流程詳解
這篇文章主要介紹了使用pygame來(lái)編寫類滿天星游戲的全記錄,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-09-09