Sympy是python中非常強(qiáng)大的符號(hào)運(yùn)算庫(kù),可以以書寫習(xí)慣表示數(shù)學(xué)表達(dá)式。下面介紹用Sympy求方程數(shù)值解的方法。

成都創(chuàng)新互聯(lián)公司于2013年開始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都做網(wǎng)站、網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元永修做網(wǎng)站,已為上家服務(wù),為永修各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220
下面代碼全部在
from sympy import *
init_printing(use_unicode=True) # 按書寫習(xí)慣輸出
下運(yùn)行。
數(shù)學(xué)表達(dá)式的輸入
首先聲明符號(hào):
x = symbols('x')
即計(jì)算機(jī)中的變量x代表數(shù)學(xué)表達(dá)式中的x。在后文輸出中所有的x會(huì)顯示為x。如果x=symbols('x0'),則輸入的方程中所有x將在輸出中以x0表示。
如果需要希臘字母
l, r = symbol('lambda rho')
l, r將分別以λ,ρ表示。可以在一個(gè)表達(dá)式中同時(shí)聲明多個(gè)符號(hào)。
或者使用var()聲明:
var('x')
與上面等效。
聲明表達(dá)式:
f = (5/x)*(exp(x)-1)-exp(x)
此時(shí)若輸出f可以看到書寫習(xí)慣的表達(dá)式。由于表達(dá)式在markdown下顯示不正常,在此不放置示例。注意f的類型是class 'sympy.core.add.Add'
求f(x)=0數(shù)值解
因?yàn)橛械暮瘮?shù)零點(diǎn)不止一個(gè),因此在Sympy中解的輸出為一個(gè)list。使用solve(表達(dá)式,自變量符號(hào))可以解析地解方程:
s, = solve(f, x)
這里根據(jù)上面f的賦值,得到s為
LambertW(-5e**-5)+5
其中用了特殊函數(shù)表達(dá)。
我們需要求這個(gè)結(jié)果的數(shù)值近似,則輸出
s.evalf()
得到輸出
4.96511423174428
就是方程f(x)=0的數(shù)值解。
求給定自變量x值時(shí)函數(shù)f(x)的值 | 將表達(dá)式轉(zhuǎn)化為函數(shù)
f.evalf(subs = {x:4.96})
得到f(4.96)的數(shù)值
0.141885450782171
如果需要以計(jì)算機(jī)函數(shù)的形式定義函數(shù)f(x),則可以使用lambdify()進(jìn)行轉(zhuǎn)化:
f_func = lambdify(x, f)
之后可以調(diào)用
f_func(4.96)
輸出
0.141885450782
利用這個(gè)方法可以測(cè)試方程的數(shù)值算法,如使用sympy接口寫牛頓法等。
利用 numpy 很簡(jiǎn)單。可以利用pip安裝
pip?install?numpy
然后(以你的方程為例),python 下
Python?2.7.10?(default,?Oct?23?2015,?19:19:21)?
[GCC?4.2.1?Compatible?Apple?LLVM?7.0.0?(clang-700.0.59.5)]?on?darwin
Type?"help",?"copyright",?"credits"?or?"license"?for?more?information.
import?numpy?as?np
a?=?np.array([[1,1],[1,-1]])
b?=?np.array([3,1])
print?np.linalg.solve(a,b)
[?2.??1.]
如果你學(xué)過 線性代數(shù),那么這段代碼很好理解。
不是很明確你需要做到什么程度,但基本可以通過以下兩個(gè)手段得到:
手工解方程得到解析解,然后套入公式
使用一些工具包例如numpy可以自動(dòng)求解
以下都給出例子
import?numpy?as?np
import?matplotlib.pyplot?as?plt
plt.axis("equal")
a?=?np.linspace(1,10,100)?#?a?的變化范圍可以自己挑,前兩個(gè)參數(shù)控制,
#?使用?numpy?自動(dòng)求解
res?=?[]
for?x?in?a:
A?=?np.mat("1,?2;?{},?-1".format(x))
b?=?np.mat("{},?10".format(x)).T
res.append(np.linalg.solve(A,?b))
#?計(jì)算完畢后取出每對(duì)x和y
x1?=?[float(r[0])?for?r?in?res]
y1?=?[float(r[1])?for?r?in?res]
plt.plot(x1,?y1)
#####################################
#?手工計(jì)算過程很簡(jiǎn)單不放上來了,直接上結(jié)果
x2?=?[(a1?+?20)?/?(2*a1?+?1)?for?a1?in?a]
y2?=?[(a1**2?-?10)?/?(2*a1?+?1)?for?a1?in?a]
plt.plot(x2,?y2)
本文歸納常見常微分方程的解析解解法以及基于Python的微分方程數(shù)值解算例實(shí)現(xiàn)。
考慮常微分方程的解析解法,我們一般可以將其歸納為如下幾類:
這類微分方程可以變形成如下形式:
兩邊同時(shí)積分即可解出函數(shù),難點(diǎn)主要在于不定積分,是最簡(jiǎn)單的微分方程。
某些方程看似不可分離變量,但是經(jīng)過換元之后,其實(shí)還是可分離變量的,不要被這種方程迷惑。
形如
的方程叫做一階線性微分方程,若 為0,則方程齊次,否則稱為非齊次。
解法: (直接套公式)
伯努利方程
形如
的方程稱為伯努利方程,這種方程可以通過以下步驟化為一階線性微分方程:
令 , 方程兩邊同時(shí)乘以 ,得到
即 .
這就將伯努利方程歸結(jié)為可以套公式的一階線性微分方程。
形如
的方程稱為二階常系數(shù)微分方程,若 ,則方程稱為齊次的,反之稱為非齊次的。以下默認(rèn)方程是非齊次的。
求解此類方程分兩步:
原方程的解 = 齊次通解 + 非齊次特解
首先假設(shè) .用特征方程法,寫出對(duì)應(yīng)的特征方程并且求解:
解的情況分為以下三種:
情況一:方程有兩個(gè)不同的實(shí)數(shù)解
假設(shè)兩個(gè)實(shí)數(shù)解分別是 , 此時(shí)方程的通解是
情況二:方程有一個(gè)二重解
假設(shè)該解等于 ,此時(shí)方程的通解是
情況三:方程有一對(duì)共軛復(fù)解
假設(shè)這對(duì)解是 , 此時(shí)方程的通解是
對(duì)于 和特征根的情況,對(duì)特解的情況做如下歸納:
形如
的方程叫做高階常系數(shù)微分方程,若 ,則方程是齊次的,否則是非齊次的。下面默認(rèn)方程是非齊次的。
求解此類方程分兩步:
原方程的解 = 齊次通解 + 非齊次特解
考慮帶有第三類邊界條件的二階常系數(shù)微分方程邊值問題
問題一:兩點(diǎn)邊值問題的解析解
由于此方程是非齊次的,故 求解此類方程分兩步:
原方程的解 = 齊次通解 + 非齊次特解
首先假設(shè) . 用特征方程法,寫出對(duì)應(yīng)的特征方程
求解得到兩個(gè)不同的實(shí)數(shù)特征根: .
此時(shí)方程的齊次通解是
由于 . 所以非齊次特解形式為
將上式代入控制方程有
求解得: , 即非齊次特解為 .
原方程的解 = 齊次通解 + 非齊次特解
于是,原方程的全解為
因?yàn)樵搯栴}給出的是第三類邊界條件,故需要求解的導(dǎo)函數(shù)
且有
將以上各式代入邊界條件
解此方程組可得: .
綜上所述,原兩點(diǎn)邊值問題的解為
對(duì)一般的二階微分方程邊值問題
假定其解存在唯一,
為求解的近似值, 類似于前面的做法,
考慮帶有第三類邊界條件的二階常系數(shù)微分方程邊值問題
問題二:有限差分方法算出其數(shù)值解及誤差
對(duì)于 原問題 ,取步長(zhǎng) h=0.2 ,用 有限差分 求其 近似解 ,并將結(jié)果與 精確解y(x)=-x-1 進(jìn)行比較.
因?yàn)?/p>
先以將區(qū)間劃分為5份為例,求出數(shù)值解
結(jié)果:
是不是解出數(shù)值解就完事了呢?當(dāng)然不是。我們可以將問題的差分格式解與問題的真解進(jìn)行比較,以得到解的可靠性。通過數(shù)學(xué)計(jì)算我們得到問題的真解為 ,現(xiàn)用范數(shù)來衡量誤差的大小:
結(jié)果:
接下來繪圖比較 時(shí)數(shù)值解與真解的差距:
結(jié)果:
將區(qū)間劃分為 份, 即 時(shí).
結(jié)果:
繪圖比較 時(shí)數(shù)值解與真解的差距:
最后,我們還可以從數(shù)學(xué)的角度分析所采用的差分格式的一些性質(zhì)。因?yàn)椴罘指袷降恼`差為 , 所以理論上來說網(wǎng)格每加密一倍,與真解的誤差大致會(huì)縮小到原來的 . 下討論網(wǎng)格加密時(shí)的變化:
結(jié)果:
方法/步驟
用Python解數(shù)學(xué)方程,需要用到Python的一個(gè)庫(kù)——SymPy庫(kù)。
SymPy是符號(hào)數(shù)學(xué)的Python庫(kù),它的目標(biāo)是成為一個(gè)全功能的計(jì)算機(jī)代數(shù)系統(tǒng),同時(shí)保持代碼簡(jiǎn)潔、易于理解和擴(kuò)展。
如果你的電腦上還沒有安裝sympy庫(kù),那就趕緊安裝吧,安裝命令:
pip3 install sympy
請(qǐng)點(diǎn)擊輸入圖片描述
先來解一個(gè)簡(jiǎn)單點(diǎn)的方程吧。
題目: 5x + 20 = 100
先直接上代碼:
from sympy import *
x = Symbol('x')
print(solve([5*x + 20 - 100], [x]))
請(qǐng)點(diǎn)擊輸入圖片描述
再來一個(gè)復(fù)雜點(diǎn)的二元一次方程吧。
題目:3x + 4y =49,?8x- y = 14
代碼如下:
from sympy import *
x = Symbol('x')
y = Symbol('y')
print(solve([3*x + 4*y - 49, 8*x - y - 14], [x, y]))
請(qǐng)點(diǎn)擊輸入圖片描述
有沒有發(fā)現(xiàn)規(guī)律呢,簡(jiǎn)單總結(jié)一下:
1)變量賦值,使用symbol函數(shù)轉(zhuǎn)換;
2)將方程式移到方程的左邊,使右邊等于0;
3)使用solve函數(shù)解方程。
當(dāng)然了,python的基礎(chǔ)語(yǔ)法必須掌握,至少需要掌握python最基礎(chǔ)的算數(shù)運(yùn)算符。
+ ?加 ---- 兩個(gè)對(duì)象相加
- ?減 ----- 得到負(fù)數(shù)或是一個(gè)數(shù)減去另一個(gè)數(shù)
* ?乘 ----- 兩個(gè)數(shù)相乘或是返回一個(gè)被重復(fù)若干次的字符串
/ ?除 ----- x 除以 y
% ?取模 ----- 返回除法的余數(shù)
** ?冪 ----- 返回x的y次冪
log() ?對(duì)數(shù)-----對(duì)數(shù) log()
下面來個(gè)難度大點(diǎn)的方程。
請(qǐng)點(diǎn)擊輸入圖片描述
代碼如下:
from sympy import *
t = Symbol('t')
x = Symbol('x')
m = integrate(sin(t)/(pi-t), (t, 0, x))
print(integrate(m, (x, 0, pi)))
請(qǐng)點(diǎn)擊輸入圖片描述
網(wǎng)頁(yè)標(biāo)題:python解方程組函數(shù) 如何解函數(shù)方程組
本文網(wǎng)址:http://chinadenli.net/article34/hppope.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、外貿(mào)建站、服務(wù)器托管、外貿(mào)網(wǎng)站建設(shè)、做網(wǎng)站、手機(jī)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)