解非线性方程的两种方法与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,求x→∞lim?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。方法如下:
這里將方程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
結果如下
總結
以上是生活随笔為你收集整理的解非线性方程的两种方法与python实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言编程非线性方程求解,c语言计算机编
- 下一篇: Python 实现定时任务的八种方案,定