解非线性方程的两种方法与python实现
寫(xiě)在開(kāi)頭: 非線性方程,就是因變量與自變量之間的關(guān)系不是線性的關(guān)系,這類(lèi)方程很多,例如平方關(guān)系、對(duì)數(shù)關(guān)系、指數(shù)關(guān)系、三角函數(shù)關(guān)系等等。求解此類(lèi)方程往往很難得到精確解,經(jīng)常需要求近似解問(wèn)題。本文將從一道數(shù)列題開(kāi)始,引出一種求解非線性方程的基礎(chǔ)方法:簡(jiǎn)單迭代法。然后講解科學(xué)計(jì)算器的求解方法:牛頓切線法。最后會(huì)用python實(shí)現(xiàn)兩種方法并可視化。
不動(dòng)點(diǎn)迭代法
引子
先來(lái)看一道簡(jiǎn)單的數(shù)列題。
已知數(shù)列an的遞推公式an+1=1an+1,且a1=1,求lim?x→∞an已知數(shù)列a_{n}的遞推公式a_{n+1}=\frac{1}{a_{n}+1} ,且a_{1}=1,求\lim_{x \to \infty}a_{n} 已知數(shù)列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?即可。但借助科學(xué)計(jì)算器還有一種投機(jī)取巧的方法:利用遞推公式不斷求ana_{n}an?。當(dāng)n足夠大時(shí),an(如a100)a_{n}(如a_{100})an?(如a100?)即可近似為ana_{n}an?的極限。而這一過(guò)程借助科學(xué)計(jì)算器的“Ans”功能可以很方便地實(shí)現(xiàn)。
可以發(fā)現(xiàn):我們用這種方法繞開(kāi)了二次方程的求根公式解出了方程x=1x+1x=\frac{1}{x+1}x=x+11?的一個(gè)實(shí)數(shù)數(shù)值解。那么對(duì)于任意形如x=g(x)x=g(x)x=g(x)的方程,是不是也可以用構(gòu)造數(shù)列an+1=g(an)a_{n+1}=g(a_{n})an+1?=g(an?)來(lái)求解呢?這就是不動(dòng)點(diǎn)迭代法了。
具體操作
不動(dòng)點(diǎn)迭代又稱(chēng)為簡(jiǎn)單迭代,用以求解方程f(x)=0f(x)=0f(x)=0。方法如下:
這里將方程f(x)=0f(x)=0f(x)=0轉(zhuǎn)換為x=g(x)x=g(x)x=g(x)是很容易的,比如對(duì)于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);但是需要注意轉(zhuǎn)換方法不唯一,這可能會(huì)影響計(jì)算結(jié)果。
缺點(diǎn)
- 只能求一個(gè)解
- 函數(shù)φ(x)在區(qū)間[a,b]內(nèi)\varphi(x)在區(qū)間[a,b]內(nèi)φ(x)在區(qū)間[a,b]內(nèi)必須滿(mǎn)足以下的收斂條件:
1. 有一階導(dǎo)數(shù)
2. 對(duì)任意x∈[a,b]x\in[a,b]x∈[a,b],總存有φ(x)∈[a,b]\varphi(x)\in[a,b]φ(x)∈[a,b]
3. 對(duì)任意x∈[a,b]x\in[a,b]x∈[a,b],總存有0<L<1,使得∣φ(x)′∣≤L<1|{\varphi(x)}'|\le L<1∣φ(x)′∣≤L<1 - 為滿(mǎn)足收斂條件,需要選取適當(dāng)初始值
牛頓切線法
鑒于不動(dòng)點(diǎn)迭代法有時(shí)無(wú)法滿(mǎn)足的收斂條件,科學(xué)計(jì)算器在求解非線性方程時(shí)會(huì)運(yùn)用另一種方法–牛頓切線法,又稱(chēng)牛頓法。
牛頓切線法也是一種迭代法。它的操作很簡(jiǎn)單,首先通過(guò)移項(xiàng)把方程轉(zhuǎn)化成求函數(shù)f(x)f(x)f(x)的零點(diǎn)的問(wèn)題。在給定一個(gè)迭代點(diǎn)xix_{i}xi?時(shí),作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軸的交點(diǎn)xi?f(xi)f′(xi)x_{i}-\frac{f(x_{i})}{f'(x_{i})}xi??f′(xi?)f(xi?)?。與不動(dòng)點(diǎn)迭代法一樣,在滿(mǎn)足結(jié)束條件時(shí)終止迭代。
如何理解這種操作呢?可以把f(x)f(x)f(x)的切線看作f(x)f(x)f(x)在xix_{i}xi?的一階泰勒近似,既然函數(shù)的切線與函數(shù)是相似的,他們的零點(diǎn)也是相近的。那就把切線的零點(diǎn)當(dāng)做目標(biāo)值的近似。
接下來(lái)是一個(gè)例子,所求方程為0.1x2?x?3=0,x0=10.1x^2-x-3=0,x_{0}=10.1x2?x?3=0,x0?=1,共迭代了兩次。
可以看到,迭代兩次后的x2x_{2}x2?已經(jīng)相當(dāng)接近xtargetx_{target}xtarget?了。
一般我們希望x盡可能接近理論值xtargetx_{target}xtarget?,但是有時(shí)確切的理論值是未知的,所以也可以令∣y∣|y|∣y∣盡可能小。現(xiàn)在我們知道了在使用卡西歐計(jì)算器時(shí),可以使用L-R的功能來(lái)估算∣y∣|y|∣y∣(即誤差)。而輸入x的功能是為了設(shè)置迭代的初始點(diǎn)。
除了求解方程,牛頓法還有更廣泛的應(yīng)用。在已知某函數(shù)的導(dǎo)數(shù)時(shí),可以令導(dǎo)數(shù)為零,解方程得函數(shù)的極值。將一元函數(shù)推廣到多元函數(shù),用向量,梯度,Heese矩陣替換自變量,導(dǎo)數(shù),二階導(dǎo)數(shù),就可以把牛頓法用于多維無(wú)約束最優(yōu)化問(wèn)題。
python實(shí)現(xiàn)
調(diào)用了numpy庫(kù)與matplotlib庫(kù)。使用同一個(gè)函數(shù)接口solve實(shí)現(xiàn)牛頓法與不動(dòng)點(diǎn)迭代法,作為示例的方程為arctan(x?7)?0.3x=0arctan(x-7)-0.3x=0arctan(x?7)?0.3x=0。在以迭代次數(shù)作為結(jié)束條件的基礎(chǔ)上,這里增加了一種終止迭代的條件:兩次x的差值∣xi+1?xi∣|x_{i+1}-x_{i}|∣xi+1??xi?∣小于某個(gè)預(yù)設(shè)的值deltadeltadelta。
由于牛頓法涉及導(dǎo)數(shù)運(yùn)算,我們用數(shù)值微分公式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)?近似導(dǎo)數(shù),由二階泰勒展開(kāi)公式可推得其誤差為O(h2)O(h^2)O(h2)。
主要函數(shù)與大致流程:
- 輸入:在func函數(shù)中輸入需要為零的函數(shù),即方程f(x)=0f(x)=0f(x)=0中的f(x)f(x)f(x),在solve函數(shù)中輸入初始迭代點(diǎn)x0x_{0}x0?,迭代次數(shù)上限iteration(默認(rèn)100),終止迭代的誤差delta(默認(rèn)1e-5)。
- 輸出:牛頓法與不動(dòng)點(diǎn)迭代法各自的解,和兩張圖ax[0],ax[1]
- 函數(shù)func():表示f(x)f(x)f(x)
- 函數(shù)derivate():對(duì)func使用數(shù)值微分求導(dǎo)
- 函數(shù)solve():繪制ax[0]的一組迭代點(diǎn)與ax[1]的一條折線
- 子圖ax[0]:函數(shù)圖像與迭代點(diǎn)
- 子圖ax[1]:f(x)f(x)f(x)隨迭代次數(shù)變化的曲線,若能有效求解,曲線將收斂與0
結(jié)果如下
總結(jié)
以上是生活随笔為你收集整理的解非线性方程的两种方法与python实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c语言编程非线性方程求解,c语言计算机编
- 下一篇: Python 实现定时任务的八种方案,定