日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

解非线性方程的两种方法与python实现

發布時間:2024/3/26 python 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 解非线性方程的两种方法与python实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫在開頭: 非線性方程,就是因變量與自變量之間的關系不是線性的關系,這類方程很多,例如平方關系、對數關系、指數關系、三角函數關系等等。求解此類方程往往很難得到精確解,經常需要求近似解問題。本文將從一道數列題開始,引出一種求解非線性方程的基礎方法:簡單迭代法。然后講解科學計算器的求解方法:牛頓切線法。最后會用python實現兩種方法并可視化。


不動點迭代法

引子

先來看一道簡單的數列題。

已知數列an的遞推公式an+1=1an+1,且a1=1,求lim?x→∞an已知數列a_{n}的遞推公式a_{n+1}=\frac{1}{a_{n}+1} ,且a_{1}=1,求\lim_{x \to \infty}a_{n} 已知數列an?的遞推公式an+1?=an?+11?,a1?=1,xlim?an?

解此題只需令lim?x→∞an=A,解方程A=1A+1\lim_{x \to \infty}a_{n} =A,解方程A=\frac{1}{A+1}limx?an?=A,解方程A=A+11?即可。但借助科學計算器還有一種投機取巧的方法:利用遞推公式不斷求ana_{n}an?。當n足夠大時,an(如a100)a_{n}(如a_{100})an?(a100?)即可近似為ana_{n}an?的極限。而這一過程借助科學計算器的“Ans”功能可以很方便地實現。

可以發現:我們用這種方法繞開了二次方程的求根公式解出了方程x=1x+1x=\frac{1}{x+1}x=x+11?的一個實數數值解。那么對于任意形如x=g(x)x=g(x)x=g(x)的方程,是不是也可以用構造數列an+1=g(an)a_{n+1}=g(a_{n})an+1?=g(an?)來求解呢?這就是不動點迭代法了。

具體操作

不動點迭代又稱為簡單迭代,用以求解方程f(x)=0f(x)=0f(x)=0。方法如下:

  • 方程轉換為x=g(x)x=g(x)x=g(x)
  • x0x_{0}x0?設定一個初值
  • xi+1=g(xi)x_{i+1}=g(x_{i})xi+1?=g(xi?)
  • 若滿足結束條件(i大于某個預設的值,或∣xi+1?xi∣|x_{i+1}-x_{i}|xi+1??xi?小于某個預設的值)xi+1x_{i+1}xi+1?為解,否則返回第3步
  • 這里將方程f(x)=0f(x)=0f(x)=0轉換為x=g(x)x=g(x)x=g(x)是很容易的,比如對于f(x)=x?cos(x)f(x)=x-cos(x)f(x)=x?cos(x),求解f(x)=0f(x)=0f(x)=0即為求解x?cos(x)=0x-cos(x)=0x?cos(x)=0,即x=cos(x)x=cos(x)x=cos(x),因此g(x)=cos(x)g(x)=cos(x)g(x)=cos(x);但是需要注意轉換方法不唯一,這可能會影響計算結果。

    缺點

    • 只能求一個解
    • 函數φ(x)在區間[a,b]內\varphi(x)在區間[a,b]內φ(x)在區間[a,b]必須滿足以下的收斂條件:
      1. 有一階導數
      2. 對任意x∈[a,b]x\in[a,b]x[a,b],總存有φ(x)∈[a,b]\varphi(x)\in[a,b]φ(x)[a,b]
      3. 對任意x∈[a,b]x\in[a,b]x[a,b],總存有0<L<1,使得∣φ(x)′∣≤L<1|{\varphi(x)}'|\le L<1φ(x)L<1
    • 為滿足收斂條件,需要選取適當初始值

    牛頓切線法

    鑒于不動點迭代法有時無法滿足的收斂條件,科學計算器在求解非線性方程時會運用另一種方法–牛頓切線法,又稱牛頓法。
    牛頓切線法也是一種迭代法。它的操作很簡單,首先通過移項把方程轉化成求函數f(x)f(x)f(x)的零點的問題。在給定一個迭代點xix_{i}xi?時,作f(x)f(x)f(x)xix_{i}xi?的切線y?f(xi)=f′(xi)(x?xi)y-f(x_{i})=f'(x_{i})(x-x_{i})y?f(xi?)=f(xi?)(x?xi?)xi+1x_{i+1}xi+1?為切線與x軸的交點xi?f(xi)f′(xi)x_{i}-\frac{f(x_{i})}{f'(x_{i})}xi??f(xi?)f(xi?)?。與不動點迭代法一樣,在滿足結束條件時終止迭代。

    如何理解這種操作呢?可以把f(x)f(x)f(x)的切線看作f(x)f(x)f(x)xix_{i}xi?的一階泰勒近似,既然函數的切線與函數是相似的,他們的零點也是相近的。那就把切線的零點當做目標值的近似。

    接下來是一個例子,所求方程為0.1x2?x?3=0,x0=10.1x^2-x-3=0,x_{0}=10.1x2?x?3=0,x0?=1,共迭代了兩次。

    可以看到,迭代兩次后的x2x_{2}x2?已經相當接近xtargetx_{target}xtarget?了。

    一般我們希望x盡可能接近理論值xtargetx_{target}xtarget?,但是有時確切的理論值是未知的,所以也可以令∣y∣|y|y盡可能小。現在我們知道了在使用卡西歐計算器時,可以使用L-R的功能來估算∣y∣|y|y(即誤差)。而輸入x的功能是為了設置迭代的初始點。

    除了求解方程,牛頓法還有更廣泛的應用。在已知某函數的導數時,可以令導數為零,解方程得函數的極值。將一元函數推廣到多元函數,用向量,梯度,Heese矩陣替換自變量,導數,二階導數,就可以把牛頓法用于多維無約束最優化問題。


    python實現

    調用了numpy庫與matplotlib庫。使用同一個函數接口solve實現牛頓法與不動點迭代法,作為示例的方程為arctan(x?7)?0.3x=0arctan(x-7)-0.3x=0arctan(x?7)?0.3x=0。在以迭代次數作為結束條件的基礎上,這里增加了一種終止迭代的條件:兩次x的差值∣xi+1?xi∣|x_{i+1}-x_{i}|xi+1??xi?小于某個預設的值deltadeltadelta

    由于牛頓法涉及導數運算,我們用數值微分公式f′(x)≈f(x+h)?f(x?h)2hf'(x)≈\frac{f(x+h)-f(x-h)}{2h}f(x)2hf(x+h)?f(x?h)?近似導數,由二階泰勒展開公式可推得其誤差為O(h2)O(h^2)O(h2)

    主要函數與大致流程:

    • 輸入:在func函數中輸入需要為零的函數,即方程f(x)=0f(x)=0f(x)=0中的f(x)f(x)f(x),在solve函數中輸入初始迭代點x0x_{0}x0?,迭代次數上限iteration(默認100),終止迭代的誤差delta(默認1e-5)。
    • 輸出:牛頓法與不動點迭代法各自的解,和兩張圖ax[0],ax[1]
    • 函數func():表示f(x)f(x)f(x)
    • 函數derivate():對func使用數值微分求導
    • 函數solve():繪制ax[0]的一組迭代點與ax[1]的一條折線
    • 子圖ax[0]:函數圖像與迭代點
    • 子圖ax[1]:f(x)f(x)f(x)隨迭代次數變化的曲線,若能有效求解,曲線將收斂與0
    import numpy as np import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽 plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負號def func(x):#需要為0的函數y=np.arctan(x-7)-0.3*x#自定義要求解的函數return y def derivate(x):#數值微分求導,h取1e-6return (func(x+1e-6)-func(x-1e-6))/2e-6 def solve(x,iteration=100,delta=1e-5,method='fixed_point'):#繪制迭代點和下降曲線doty=[func(x)]#保存迭代點的縱坐標,用來繪制折線圖,先記錄初始點n=1#記錄迭代次數for i in range(iteration):if(method=='fixed_point'):#不動點迭代xnext=func(x)+xcolors="blue"if(method=='newton'):#牛頓迭代xnext=x-func(x)/derivate(x)colors="orange"ax[0].scatter(xnext,func(xnext),marker='o',s=10,color=colors,alpha=1,zorder=3)doty.append(func(xnext))#添加迭代點的縱坐標n=n+1if(abs(x-xnext)<delta):#新增的終止條件breakx=xnextax[1].plot(np.arange(0,n),doty,'o-',markersize=3)#繪制函數值下降曲線return x;#畫布的基礎設置 X=np.linspace(-15,20,500) # X軸坐標數據 Y =func(X) # Y軸坐標數據 fig, ax = plt.subplots(1, 2, figsize=(10, 4),dpi=120)#創建畫布 ax[0].tick_params(labelsize=12)#坐標字號 ax[1].tick_params(labelsize=12) ax[0].set_xlabel('$x$')#坐標名稱 ax[0].set_ylabel('$y$') ax[1].set_xlabel('迭代次數') ax[1].set_ylabel('函數值') ax[0].grid()#增加網格 ax[1].grid()ax[0].plot(X,0*X,color="black",linewidth=1,zorder=1)#作圖y=0 ax[0].plot(X,Y,label="$f(x)$",color="black",linewidth=1,zorder=2)#作出函數圖像#繪制兩種方法的迭代點與函數下降曲線 ax[0].scatter(8,func(8),color="red",s=10,label="初始點")#繪制初始點 ans1=solve(8,100,method='fixed_point') ans2=solve(8,100,method='newton') ax[0].legend(fontsize=8)#設置圖例 ax[1].legend(['不動點迭代法','牛頓法'],fontsize=8)print('不動點迭代法的結果:'+str(ans1)) print('牛頓法的結果:'+str(ans2))plt.show()

    結果如下

    總結

    以上是生活随笔為你收集整理的解非线性方程的两种方法与python实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。