基于Python利用Newton-Raphson方法求解非线性方程组

       Python第三方库scipy.optimize中的fsolve和root这两个函数可用于非线性方程组的求解。但其更适用于结构形式稍显简单的方程组求解。对于多变量结构复杂的非线性方程组的求解操作起来稍显困难。因此,自己动手编写求解非线性方程组的程序。

      本文采用了Newton-Raphson求解方法,其中利用了一阶差商代替偏导数的求解得到雅可比矩阵。

算法流程:

      首先取初值 X=(x_{1},x_{2},...,x_{n})^{T},h>0,0<t<1,然后做以下迭代:

(1) 计算 f_{i}\Rightarrow B(i), i=1,2,...,n

(2) 如果满足max|B|<\varepsilon,则方程组的实数解为X=(x_{1},x_{2},...,x_{n})^{T}迭代过程结束,否则继续;

(3)f_{i}(X_{j})\Rightarrow A(i,j), (i,j=1,2,...,n),其中X=(x_{1},x_{2},...,x_{j},x_{j+1},...,x_{n})^{T}

(4) 解线性方程组AZ=B,其中Z=(z_{1},z_{2},...,z_{3})^{T},并计算

                                                 \beta =1-\sum_{1}^{n}z_{j}

(5) 计算x_{i}-hz_{i}/\beta \Rightarrow x_{i+1}, i=1,2,...,n

(6)  转到(1),重复以上过程直到 X 满足精度要求为止。

python源代码如下:

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()     

 

你可能感兴趣的:(python,科学计算)