用Python學數學之Sympy代數符號運算

在咱們初、高中和大學近10年的學習時間裏,數學一直佔據着很是大的份量,可是回憶過去能夠發現,咱們把大量的時間都花在反覆解題、不斷運算上,計算方法、運算技巧、筆算能力以及數學公式的記憶彷彿成了咱們學習數學的所有。這些記憶和技巧沒幾年就忘掉了,但不少人甚至還記得那份陰影;筆算與解題在AI、圖形圖像、數據分析等上被軟件所取代。那咱們學生時代的數學還剩下什麼呢?

計算器與數學

提及數學計算器,咱們常見的是加減乘除四則運算,有了它,咱們就能夠擺脫筆算和心算的痛苦。四位數以上的加減乘除在數學的原理上其實並不難,可是若是不借助於計算器,光依賴咱們的運算能力(筆算和心算),不只運算的準確度大打折扣,並且還會讓咱們對數學的運用停留在一個很是淺的層次。python

儘管四則運算如此簡單,可是多位數運算的心算卻在咱們生活中被歸爲天才般的能力。可是數學的應用應該生活化、普及化,而不是隻屬於天才的專利,計算器改變了這一切,這就是計算器的魅力。
計算器還能夠作科學運算,好比乘方、開方、指數、對數、三角函數等,儘管這些知識在咱們初中時代,經過紙筆也是能運算起來的,可是也僅限於一些極其經常使用和簡單的運算,一旦複雜起來,經過紙筆來運算就是一項複雜的工程了。因此說, 計算器可讓咱們離數學的應用更近

可是咱們學生時代所學的數學可遠不止這些,尤爲是高等數學(微積分)、線性代數、機率統計等數學知識應用很是普遍(我也是後來才知道),可是因爲他們的運算很是複雜,咱們即使掌握了這些知識,想要應用它又談何容易,那有沒有微積分、線性代數、機率統計等的計算器呢?程序員

答案是有的,它們就是計算機代數系統Computer Algebra System,簡稱CAS,Python的Sympy庫也支持帶有數學符號的微積分、線性代數等進行運算。函數

有了計算器,咱們才能真正脫離數學複雜的解題自己,把精力花在對數學原理和應用的學習上,而這纔是(在工做方面)數學學習的意義。

計算機代數系統

Sympy能夠實現數學符號的運算,用它來進行數學表達式的符號推導和驗算,處理帶有數學符號的導數、極限、微積分、方程組、矩陣等,就像科學計算器同樣簡單,相似於計算機代數系統CAS,雖然CAS一般是可視化軟件,可是維基百科上也把Sympy歸爲CAS。工具

幾大知名的數學軟件好比MathematicaMaximaMatlab(需Symbolic Math Toolbox)Maple等均可以作符號運算,在上篇文章中咱們已經拿Python和R、Matlab對比了,顯然Python在指定場景下確實優點很是明顯,因而我又調研了一下Sympy與Mathematica的比較,在輸入公式以及生成圖表方面,Sympy確實不行(這一點Python有其餘庫來彌補),Mathematica可以作什麼,Sympy基本也能作什麼。學習

因此說Python在專業數學(數學、數據科學等)領域,因爲其擁有很是多並且強大的第三方庫,構成了一個極其完善的生態鏈,即便是面對世界上最爲強勢最爲硬核的軟件也是絲絕不虛的。code

本專欄 用Python學數學的下一期也會介紹一些很是實用的數學工具和數學教材資源,讓數學的學習更簡單更生動。

Sympy的符號運算

若是以前是學數學相關專業瞭解計算機代數系統CAS,就會對數學符號的運算比較熟悉,而若是以前是程序員,可能會有點不太明白,下面咱們就來了解一下。教程

Sympy與Math函數的區別ip

咱們先來看一下Sympy庫和Python內置的Math函數對數值計算的處理有什麼不一樣。爲了讓代碼可執行,下面的代碼都是基於Python3的完整代碼。資源

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

執行以後,結果顯示爲:get

2.8284271247461903
2*sqrt(2)

math模塊是直接求解出一個浮點值,而Sympy則是用數學符號表示出結果,結合LaTex的語法就能夠得出咱們在課本里最熟悉的的:$2\sqrt{2}$。

數學符號與表達式

咱們要對數學方程組、微積分等進行運算時,就會遇到變量好比x,y,z,f等的問題,也會遇到求導、積分等代數符號表達式,而Sympy就能夠保留變量,計算有代數符號的表達式的。

from sympy import *
x = Symbol('x')
y = Symbol('y')
k, m, n = symbols('k m n')
print(3*x+y**3)

輸出的結果爲:3*x + y**3,轉化爲LaTex表示法以後結果爲$3x+y^3$,輸出的結果就帶有x和y變量。Symbol()函數定義單個數學符號;symbols()函數定義多個數學符號。

摺疊與展開表達式

factor()函數能夠摺疊表達式,而expand()函數能夠展開表達式,好比表達式:$x^4+xy+8x$,摺疊以後應該是$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)

表達式的摺疊與展開,對應的數學知識就是因式分解,相關的數學知識在人教版初二的教程裏。用Python學習數學專欄的目的就是要Python與初高中、大學的數學學習結合起來,讓數學變得更加簡單生動。

表達式化簡

simplify()函數能夠對錶達式進行化簡。有一些表達式看起來會比較複雜,就拿人教版初二上的一道多項式的乘法爲例,簡化$(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)

求解方程組

在人教版的數學教材裏,咱們初一上會接觸一元一次方程組,初一下就會接觸二元一次方程、三元一次方程組,在初三上會接觸到一元二次方程,使用Sympy的solve()函數就能輕鬆解題。

解一元一次方程

咱們來求解這個一元一次方程組。(題目來源於人教版七年級數學上)
$$6 \times x + 6 \times(x-2000)=150000$$

from sympy import *
x = Symbol('x')
print(solve(6*x + 6*(x-2000)-150000,x))

咱們須要掌握Python的代碼符號和數學符號之間的對應關係,解一元一次方程就很是簡單。

解二元一次方程組

咱們來看如何求解二元一次方程組。(題目來自人教版七年級數學下)

$$ \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$$。

解三元一次方程組

咱們來看如何解三元一次方程組。(題目來自人教版七年級數學下)

$$ \begin{cases} x+y+z=12,\\ x+2y+5z=22,\\ x=4y. \end{cases} $$

執行以後,很快能夠得出結果{x: 8, y: 2, z: 2},也就是
$$x=8,y=2,z=2$$

解一元二次方程組

好比咱們來求解人教版九年級一元二次方程組比較經典的一個題目,$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)

執行以後得出的結果爲[(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)],咱們知道根與係數的關係二次方程會有兩個解,這裏的格式就是一個列表。轉爲咱們常見的數學公式即爲:
$$\frac{-b+\sqrt{-4ac+b^2}}{2a} 、-\frac{b+\sqrt{-4ac+b^2}}{2a}$$

微積分Calculus

微積分是大學高等數學裏很是重要的學習內容,好比求極限、導數、微分、不定積分、定積分等都是可使用Sympy來運算的。
求極限
Sympy是使用limit(表達式,變量,極限值)函數來求極限的,好比咱們要求$\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)

執行後便可獲得結果爲1。

求導

可使用diff(表達式,變量,求導的次數)函數對錶達式求導,好比咱們要對$sin(x)e^x$進行$x$求導,以及求導兩次,代碼以下:

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)

求導一次的結果就是exp(x)*sin(x) + exp(x)*cos(x),也就是$e^xsin(x)+e^xcos(x)$;求導兩次的結果是2*exp(x)*cos(x),也就是
$$2e^xcosx$$

求不定積分

Sympy是使用integrate(表達式,變量)來求不定積分的,好比咱們要求$\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)

執行以後的結果爲:exp(x)*sin(x) 轉化以後爲:
$$e^xsin(x)$$

求定積分

Sympy一樣是使用integrate()函數來作定積分的求解,只是語法不一樣:integrate(表達式,(變量,下區間,上區間)),咱們來看若是求解
$\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)

執行以後的結果爲sqrt(2)*sqrt(pi)/2,也就是
$$\frac{\sqrt{2}\sqrt{\pi}}{2}$$

Sympy可以作的也遠不止這些,初高中、大學的數學運算題在Sympy極爲豐富的功能裏不過只是開胃入門小菜而已。

相關文章
相關標籤/搜索