用Python學(xué)數(shù)學(xué)之Sympy代數(shù)符號運(yùn)算

在我們初、高中和大學(xué)近10年的學(xué)習(xí)時間里,數(shù)學(xué)一直占據(jù)著非常大的分量,但是回憶過去可以發(fā)現(xiàn),我們把大量的時間都花在反復(fù)解題、不斷運(yùn)算上,計(jì)算方法、運(yùn)算技巧、筆算能力以及數(shù)學(xué)公式的記憶仿佛成了我們學(xué)習(xí)數(shù)學(xué)的全部。這些記憶和技巧沒幾年就忘掉了,但很多人甚至還記得那份陰影;筆算與解題在AI、圖形圖像、數(shù)據(jù)分析等上被軟件所取代。那我們學(xué)生時代的數(shù)學(xué)還剩下什么呢?

計(jì)算器與數(shù)學(xué)

說起數(shù)學(xué)計(jì)算器,我們常見的是加減乘除四則運(yùn)算,有了它,我們就可以擺脫筆算和心算的痛苦。四位數(shù)以上的加減乘除在數(shù)學(xué)的原理上其實(shí)并不難,但是如果不借助于計(jì)算器,光依賴我們的運(yùn)算能力(筆算和心算),不僅運(yùn)算的準(zhǔn)確度大打折扣,而且還會讓我們對數(shù)學(xué)的運(yùn)用停留在一個非常淺的層次。

盡管四則運(yùn)算如此簡單,但是多位數(shù)運(yùn)算的心算卻在我們生活中被歸為天才般的能力。但是數(shù)學(xué)的應(yīng)用應(yīng)該生活化、普及化,而不是只屬于天才的專利,計(jì)算器改變了這一切,這就是計(jì)算器的魅力。
計(jì)算器還可以做科學(xué)運(yùn)算,比如乘方、開方、指數(shù)、對數(shù)、三角函數(shù)等,盡管這些知識在我們初中時代,通過紙筆也是能運(yùn)算起來的,但是也僅限于一些極其常用和簡單的運(yùn)算,一旦復(fù)雜起來,通過紙筆來運(yùn)算就是一項(xiàng)復(fù)雜的工程了。所以說,計(jì)算器可以讓我們離數(shù)學(xué)的應(yīng)用更近。

但是我們學(xué)生時代所學(xué)的數(shù)學(xué)可遠(yuǎn)不止這些,尤其是高等數(shù)學(xué)(微積分)、線性代數(shù)、概率統(tǒng)計(jì)等數(shù)學(xué)知識應(yīng)用非常廣泛(我也是后來才知道),但是由于他們的運(yùn)算非常復(fù)雜,我們即便掌握了這些知識,想要應(yīng)用它又談何容易,那有沒有微積分、線性代數(shù)、概率統(tǒng)計(jì)等的計(jì)算器呢?

答案是有的,它們就是計(jì)算機(jī)代數(shù)系統(tǒng)Computer Algebra System,簡稱CAS,Python的Sympy庫也支持帶有數(shù)學(xué)符號的微積分、線性代數(shù)等進(jìn)行運(yùn)算。

有了計(jì)算器,我們才能真正脫離數(shù)學(xué)復(fù)雜的解題本身,把精力花在對數(shù)學(xué)原理和應(yīng)用的學(xué)習(xí)上,而這才是(在工作方面)數(shù)學(xué)學(xué)習(xí)的意義。

計(jì)算機(jī)代數(shù)系統(tǒng)

Sympy可以實(shí)現(xiàn)數(shù)學(xué)符號的運(yùn)算,用它來進(jìn)行數(shù)學(xué)表達(dá)式的符號推導(dǎo)和驗(yàn)算,處理帶有數(shù)學(xué)符號的導(dǎo)數(shù)、極限、微積分、方程組、矩陣等,就像科學(xué)計(jì)算器一樣簡單,類似于計(jì)算機(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在指定場景下確實(shí)優(yōu)勢非常明顯,于是我又調(diào)研了一下Sympy與Mathematica的比較,在輸入公式以及生成圖表方面,Sympy確實(shí)不行(這一點(diǎn)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í)用的數(shù)學(xué)工具和數(shù)學(xué)教材資源,讓數(shù)學(xué)的學(xué)習(xí)更簡單更生動。

Sympy的符號運(yùn)算

如果之前是學(xué)數(shù)學(xué)相關(guān)專業(yè)了解計(jì)算機(jī)代數(shù)系統(tǒng)CAS,就會對數(shù)學(xué)符號的運(yùn)算比較熟悉,而如果之前是程序員,可能會有點(diǎn)不太明白,下面我們就來了解一下。

Sympy與Math函數(shù)的區(qū)別

我們先來看一下Sympy庫和Python內(nèi)置的Math函數(shù)對數(shù)值計(jì)算的處理有什么不同。為了讓代碼可執(zhí)行,下面的代碼都是基于Python3的完整代碼。

import sympy,math
print(math.sqrt(8))
print(sympy.sqrt(8))

執(zhí)行之后,結(jié)果顯示為:

2.8284271247461903
2*sqrt(2)

math模塊是直接求解出一個浮點(diǎn)值,而Sympy則是用數(shù)學(xué)符號表示出結(jié)果,結(jié)合LaTex的語法就可以得出我們在課本里最熟悉的的:2\sqrt{2}

數(shù)學(xué)符號與表達(dá)式

我們要對數(shù)學(xué)方程組、微積分等進(jìn)行運(yùn)算時,就會遇到變量比如x,y,z,f等的問題,也會遇到求導(dǎo)、積分等代數(shù)符號表達(dá)式,而Sympy就可以保留變量,計(jì)算有代數(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ù)雜,就拿人教版初二上的一道多項(xiàng)式的乘法為例,簡化(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 \times x + 6 \times(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é)下)
\begin{cases} x+ y =10,\\ 2 \times 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é)下)
\begin{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}

微積分Calculus

微積分是大學(xué)高等數(shù)學(xué)里非常重要的學(xué)習(xí)內(nèi)容,比如求極限、導(dǎo)數(shù)、微分、不定積分、定積分等都是可以使用Sympy來運(yùn)算的。
求極限
Sympy是使用limit(表達(dá)式,變量,極限值)函數(shù)來求極限的,比如我們要求\lim \limits_{x \to 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^x\sin{(x)} + e^x\cos{(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極為豐富的功能里不過只是開胃入門小菜而已。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容