但是我們學(xué)生時代所學(xué)的數(shù)學(xué)可遠(yuǎn)不止這些,尤其是高等數(shù)學(xué)(微積分)、線性代數(shù)、概率統(tǒng)計等數(shù)學(xué)知識應(yīng)用非常廣泛(我也是后來才知道),但是由于他們的運(yùn)算非常復(fù)雜,我們即便掌握了這些知識,想要應(yīng)用它又談何容易,那有沒有微積分、線性代數(shù)、概率統(tǒng)計等的計算器呢?
答案是有的,它們就是計算機(jī)代數(shù)系統(tǒng)Computer Algebra System,簡稱CAS,Python的Sympy庫也支持帶有數(shù)學(xué)符號的微積分、線性代數(shù)等進(jìn)行運(yùn)算。
有了計算器,我們才能真正脫離數(shù)學(xué)復(fù)雜的解題本身,把精力花在對數(shù)學(xué)原理和應(yīng)用的學(xué)習(xí)上,而這才是(在工作方面)數(shù)學(xué)學(xué)習(xí)的意義。Sympy可以實現(xiàn)數(shù)學(xué)符號的運(yùn)算,用它來進(jìn)行數(shù)學(xué)表達(dá)式的符號推導(dǎo)和驗算,處理帶有數(shù)學(xué)符號的導(dǎo)數(shù)、極限、微積分、方程組、矩陣等,就像科學(xué)計算器一樣簡單,類似于計算機(jī)代數(shù)系統(tǒng)CAS,雖然CAS通常是可視化軟件,但是維基百科上也把Sympy歸為CAS。
幾大知名的數(shù)學(xué)軟件比如Mathematica、Maxima、Matlab(需Symbolic Math Toolbox)、Maple等都可以做符號運(yùn)算,在上篇文章中我們已經(jīng)拿Python和R、Matlab對比了,顯然Python在指定場景下確實優(yōu)勢非常明顯,于是我又調(diào)研了一下Sympy與Mathematica的比較,在輸入公式以及生成圖表方面,Sympy確實不行(這一點Python有其他庫來彌補(bǔ)),Mathematica能夠做什么,Sympy基本也能做什么。
所以說Python在專業(yè)數(shù)學(xué)(數(shù)學(xué)、數(shù)據(jù)科學(xué)等)領(lǐng)域,由于其擁有非常多而且強(qiáng)大的第三方庫,構(gòu)成了一個極其完善的生態(tài)鏈,即使是面對世界上最為強(qiáng)勢最為硬核的軟件也是絲毫不虛的。
本專欄用Python學(xué)數(shù)學(xué)的下一期也會介紹一些非常實用的數(shù)學(xué)工具和數(shù)學(xué)教材資源,讓數(shù)學(xué)的學(xué)習(xí)更簡單更生動。如果之前是學(xué)數(shù)學(xué)相關(guān)專業(yè)了解計算機(jī)代數(shù)系統(tǒng)CAS,就會對數(shù)學(xué)符號的運(yùn)算比較熟悉,而如果之前是程序員,可能會有點不太明白,下面我們就來了解一下。
Sympy與Math函數(shù)的區(qū)別
我們先來看一下Sympy庫和Python內(nèi)置的Math函數(shù)對數(shù)值計算的處理有什么不同。為了讓代碼可執(zhí)行,下面的代碼都是基于Python3的完整代碼。
import sympy,math print(math.sqrt(8)) print(sympy.sqrt(8))
執(zhí)行之后,結(jié)果顯示為:
2.8284271247461903 2*sqrt(2)
math模塊是直接求解出一個浮點值,而Sympy則是用數(shù)學(xué)符號表示出結(jié)果,結(jié)合LaTex的語法就可以得出我們在課本里最熟悉的的:$2sqrt{2}$。
數(shù)學(xué)符號與表達(dá)式
我們要對數(shù)學(xué)方程組、微積分等進(jìn)行運(yùn)算時,就會遇到變量比如x,y,z,f等的問題,也會遇到求導(dǎo)、積分等代數(shù)符號表達(dá)式,而Sympy就可以保留變量,計算有代數(shù)符號的表達(dá)式的。
from sympy import * x = Symbol('x') y = Symbol('y') k, m, n = symbols('k m n') print(3*x+y**3)
輸出的結(jié)果為:3*x + y**3
,轉(zhuǎn)化為LaTex表示法之后結(jié)果為$3x+y^3$,輸出的結(jié)果就帶有x和y變量。Symbol()函數(shù)定義單個數(shù)學(xué)符號;symbols()函數(shù)定義多個數(shù)學(xué)符號。
折疊與展開表達(dá)式
factor()
函數(shù)可以折疊表達(dá)式,而expand()
函數(shù)可以展開表達(dá)式,比如表達(dá)式:$x^4+xy+8x$,折疊之后應(yīng)該是$x(x^3+y+8)$。我們來看具體的代碼:
from sympy import * x,y = symbols('x y') expr=x**4+x*y+8*x f_expr=factor(expr) e_expr=expand(f_expr) print(f_expr) print(e_expr)
表達(dá)式的折疊與展開,對應(yīng)的數(shù)學(xué)知識就是因式分解,相關(guān)的數(shù)學(xué)知識在人教版初二的教程里。用Python學(xué)習(xí)數(shù)學(xué)專欄的目的就是要Python與初高中、大學(xué)的數(shù)學(xué)學(xué)習(xí)結(jié)合起來,讓數(shù)學(xué)變得更加簡單生動。
表達(dá)式化簡
simplify()函數(shù)可以對表達(dá)式進(jìn)行化簡。有一些表達(dá)式看起來會比較復(fù)雜,就拿人教版初二上的一道多項式的乘法為例,簡化$(2x)^3(-5xy^2)$。
from sympy import * x,y = symbols('x y') expr=(2*x)**3*(-5*x*y**2) s_expr=simplify(expr) print(s_expr)
在人教版的數(shù)學(xué)教材里,我們初一上會接觸一元一次方程組,初一下就會接觸二元一次方程、三元一次方程組,在初三上會接觸到一元二次方程,使用Sympy的solve()函數(shù)就能輕松解題。
解一元一次方程
我們來求解這個一元一次方程組。(題目來源于人教版七年級數(shù)學(xué)上)
$$6 imes x + 6 imes(x-2000)=150000$$
from sympy import * x = Symbol('x') print(solve(6*x + 6*(x-2000)-150000,x))
我們需要掌握Python的代碼符號和數(shù)學(xué)符號之間的對應(yīng)關(guān)系,解一元一次方程就非常簡單。
解二元一次方程組
我們來看如何求解二元一次方程組。(題目來自人教版七年級數(shù)學(xué)下)
$$ egin{cases} x+ y =10,\ 2 imes x+ y=16 end{cases} $$
from sympy import * x,y = symbols('x y') print(solve([x + y-10,2*x+y-16],[x,y]))
很快就可以得出{x: 6, y: 4}
,也就是
$$x=6,y=4$$。
解三元一次方程組
我們來看如何解三元一次方程組。(題目來自人教版七年級數(shù)學(xué)下)
$$ egin{cases} x+y+z=12,\ x+2y+5z=22,\ x=4y. end{cases} $$
執(zhí)行之后,很快可以得出結(jié)果{x: 8, y: 2, z: 2}
,也就是
$$x=8,y=2,z=2$$
解一元二次方程組
比如我們來求解人教版九年級一元二次方程組比較經(jīng)典的一個題目,$ax^2+bx+c=0$.
from sympy import * x,y = symbols('x y') a,b,c=symbols('a b c') expr=a*x**2 + b*x + c s_expr=solve( expr, x) print(s_expr)
執(zhí)行之后得出的結(jié)果為[(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)]
,我們知道根與系數(shù)的關(guān)系二次方程會有兩個解,這里的格式就是一個列表。轉(zhuǎn)為我們常見的數(shù)學(xué)公式即為:
$$frac{-b+sqrt{-4ac+b^2}}{2a} 、-frac{b+sqrt{-4ac+b^2}}{2a}$$
微積分是大學(xué)高等數(shù)學(xué)里非常重要的學(xué)習(xí)內(nèi)容,比如求極限、導(dǎo)數(shù)、微分、不定積分、定積分等都是可以使用Sympy來運(yùn)算的。
求極限
Sympy是使用limit(表達(dá)式,變量,極限值)函數(shù)來求極限的,比如我們要求$lim limits_{x o 0} frac{sinx(x)}{x}$的值。
from sympy import * x, y, z = symbols('x y z') expr = sin(x)/x l_expr=limit(expr, x, 0) print(l_expr)
執(zhí)行后即可得到結(jié)果為1。
求導(dǎo)
可以使用diff(表達(dá)式,變量,求導(dǎo)的次數(shù))函數(shù)對表達(dá)式求導(dǎo),比如我們要對$sin(x)e^x$進(jìn)行$x$求導(dǎo),以及求導(dǎo)兩次,代碼如下:
from sympy import * x,y = symbols('x y') expr=sin(x)*exp(x) diff_expr=diff(expr, x) diff_expr2=diff(expr,x,2) print(diff_expr) print(diff_expr2)
求導(dǎo)一次的結(jié)果就是exp(x)*sin(x) + exp(x)*cos(x)
,也就是$e^xsin(x)+e^xcos(x)$;求導(dǎo)兩次的結(jié)果是2*exp(x)*cos(x)
,也就是
$$2e^xcosx$$
求不定積分
Sympy是使用integrate(表達(dá)式,變量)來求不定積分的,比如我們要求$int(e^xsin{(x)} + e^xcos{(x)}),dx$
from sympy import * x,y = symbols('x y') expr=exp(x)*sin(x) + exp(x)*cos(x) i_expr=integrate(expr,x) print(i_expr)
執(zhí)行之后的結(jié)果為:exp(x)*sin(x)
轉(zhuǎn)化之后為:
$$e^xsin(x)$$
求定積分
Sympy同樣是使用integrate()函數(shù)來做定積分的求解,只是語法不同:integrate(表達(dá)式,(變量,下區(qū)間,上區(qū)間)),我們來看如果求解
$int_{-infty}^infty sin{(x^2)},dx$
from sympy import * x,y = symbols('x y') expr=sin(x**2) i_expr=integrate(expr, (x, -oo, oo)) print(i_expr)
執(zhí)行之后的結(jié)果為sqrt(2)*sqrt(pi)/2
,也就是
$$frac{sqrt{2}sqrt{pi}}{2}$$
Sympy能夠做的也遠(yuǎn)不止這些,初高中、大學(xué)的數(shù)學(xué)運(yùn)算題在Sympy極為豐富的功能里不過只是開胃入門小菜而已。
本篇文章到這里就已經(jīng)全部結(jié)束了,更多其他精彩內(nèi)容可以關(guān)注PHP中文網(wǎng)的python視頻教程欄目!
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com