Python第三方库scipy.optimize中的fsolve和root这两个函数可用于非线性方程组的求解。但其更适用于结构形式稍显简单的方程组求解。对于多变量结构复杂的非线性方程组的求解操作起来稍显困难。因此,自己动手编写求解非线性方程组的程序。
本文采用了Newton-Raphson求解方法,其中利用了一阶差商代替偏导数的求解得到雅可比矩阵。
首先取初值 ,然后做以下迭代:
(1) 计算
(2) 如果满足,则方程组的实数解为迭代过程结束,否则继续;
(3),其中
(4) 解线性方程组,其中,并计算
(5) 计算
(6) 转到(1),重复以上过程直到 X 满足精度要求为止。
import numpy as np
from scipy.linalg import solve
class NR:
def __init__(self,h=1e-2,t=0.5,esp1=1e-8,para_num=2):
"""
初始化函数
h:迭代步长
t:学习率
esp1:数值解误差范围
para_num:非线性方程组求解参数个数
"""
self.h=h
self.t=t
self.esp1=esp1
self.para_num=para_num
self.X=[]
for p in range(para_num):
self.X.append(0.33e-1) #为求解变量赋初值
def solvefounction(self,X):
"""
输入待求解方程组
"""
#本例中为二元非线性方程组,故由F1,F2表示。如果为n元非线性方程组可由F1...Fn表示
F1=4*X[0]**2+9*X[1]**2-16*X[0]-54*X[1]+61
F2=X[0]*X[1]-2*X[0]+1
F=[F1,F2]
return F
def solve(self):
"""
求解非线性方程组
"""
num=0
A=np.zeros((self.para_num,self.para_num),dtype=np.float64)
Finit=self.solvefounction(self.X)
themax=np.max(np.abs(np.array(Finit)))
while themax>self.esp1:
for m in range(self.para_num):
for n in range(self.para_num):
xori=self.X[n]
self.X[n]=self.X[n]+self.h
Fnew=self.solvefounction(self.X)
A[m,n]=Fnew[m]
self.X[n]=xori
ab=solve(A,np.array(Finit))
beta=1-np.sum(ab)
for i in range(self.para_num):
self.X[i]=self.X[i]-self.h*ab[i]/beta
self.h=self.h*self.t
Finit=self.solvefounction(self.X)
themax=np.max(np.abs(np.array(Finit)))
num+=1
if num==1000: #如果迭代次数大于1000次,强制停止
break
print('迭代次数为:',num)
return self.X
def main():
new=NR()
Solution=new.solve()
print('方程组的解为:',Solution)
if __name__ == '__main__':
main()