天天看點

Python圈中的符号計算庫-Sympy

import math

math.sqrt(8)

2.8284271247461903      

我們看看Python中結果

math.sqrt(8).math.sqrt(8)

8.000000000000002      

本以為會得到8.0,但沒想到得到8.000000000000002。

一、為什麼會這樣?

如果我們平常計算的任務常常有類似于上面的例子這樣的表達式,那麼直接用python計算其結果隻是真實值的逼近。如果這樣的計算很大很多,誤差會逐漸積累,這是我們不能忍受的,是以這時候就需要Python能處理這種數學符号計算。

二、什麼是數學符号計算?

數學符号計算能處理表征數字的符号計算。這意味着數學對象被精确地表示,而不是近似地表示,而具有未被計算的變量的數學表達式被留在符号形式中。

sympy庫簡介

Sympy是Python的一個數學符号計算庫。它目的在于成為一個富有特色的計算機代數系統。它保證自身的代碼盡可能的簡單,且易于了解,容易擴充。Sympy完全由Python寫成,不需要額外的庫。

sympy的表達式與我們平常的手寫的數學表達式略微有所差別,下面是sympy的方程表示符号

  • 加号  +
  • 減号  -
  • 除号  /
  • 乘号  *
  • 等号  Eq()
  • 指數  **
  • 對數  log()
  • e的指數次幂  exp()

上面的例子我們用Python實作一下。

import sympy

sympy.sqrt(8)

2*sqrt(2)      

用sympy計算

sympy.sqrt(8)*sympy.sqrt(8)

8      

三、簡單學一下sympy中的幾個執行個體

  • 定義數學符号(類似于數學中的變量)
  • 展開與折疊
  • 簡化表達式
  • 解方程
  • 指派計算
  • log計算
  • 導數
  • 積分
  • 求極限

3.1  定義數學符号

讓我們定義一個符号表達式代表數學表達式 x+2yx+2y。首先我們要注意到python中的變量必須指派才能使用,是以無法表達該數學表達式。是以這裡一定要引入特殊的符号,這裡有兩種方法

  • 方法一
from sympy import symbols

x,y = symbols('x y')
expr = x + 2*y

expr
x + 2*y      
  • 方法二
from sympy.abc import x,y

expr2 = x + 2*y

expr2
x + 2*y      

**當數學表達式中的變量不是x,y這種單一字元,而是result這種多個字元長度的變量時,隻能用方法一。

3.2 展開與折疊

from sympy import expand,factor
from sympy.abc import x,y

expr = x**2+x*y+3*x

expr
x**2 + x*y + 3*x      
  • 折疊
factor(expr)

x**2 + x*y + 3*x      
  • 展開
expr2 = x*(x+y+3)
expand(expr2)
x**2 + x*y + 3*x      

3.3 簡化表達式

有時候我們需要簡化表達式

  • 普通的化簡
from sympy import simplify
from sympy.abc import x

simplify((x**3 + x**2 - x - 1)/(x**2 + 2*x + 1))
x - 1      
  • 三角化簡trigsimp
from sympy import trigsimp,sin,cos
from sympy.abc import x,y
y = sin(x)/cos(x)

trigsimp(y)
tan(x)      
  • 指數化簡
from sympy import powsimp
from sympy.abc import x,a,b
y = x**a * x**b

y
x**a*x**b

#指數化簡
powsimp(y)
x**(a + b)      

3.4 解方程

注意在python中=是指派的意思,==雖然表示等于,但是會有很大的問題。在sympy中,我們使用Eq(x,y)表示x=y

from sympy.abc import x,y
from sympy import solve,linsolve,Eq

#對一個方程求解,使用solve
solve(Eq(2*x-1,3), x)
[2]      

使用linsolve([方程1,方程2,...],(變量1,變量2,...))

#對多個方程求解,使用linsolve。方程的解為x=-1,y=3
linsolve([x+2*y-5,2*x+y-1], (x,y))

{(-1, 3)}      

3.5 指派計算

from sympy.abc import x,y
from sympy import sin,cos
y = sin(x)+cos(x)

y
sin(x) + cos(x)

y.subs(x, x**2)
sin(x**2) + cos(x**2)      

這裡的指派,不僅可以實作變量的替換,還可以賦與數字,進行計算。

y.subs(x, 0)
1      

3.6 log運算

from sympy import log,expand_log
from sympy.abc import x,y,e

#expand_log為展開log,但需要将force=True,展開才能發生
expand_log(log(x**3), force=True)
3*log(x)

#expand_log為展開log,但需要将force=True,展開才能發生
expand_log(log(x**3))
log(x**3)

expand_log(log(e**x), force=True)
x*log(e)      

3.7 導數

from sympy import diff,sin,cos
from sympy.abc import x,y,z,f

#對sin(x)求導
diff(sin(x))
cos(x)

diff(cos(x))
-sin(x)      

偏導

#求偏導
f = 3*x**2*y*z

diff(f, x,y)
6*x*z      

3.8 積分

from sympy.abc import pi,x
from sympy import integrate,sin

integrate(sin(x), (x,0,pi))
-cos(pi) + 1      

3.9 極限

from sympy.abc import x
from sympy import limit

limit(1/x, x, 0, '+')
oo      

3.10 展開式

高數中有泰勒展開式,拉格朗日展開式。

e^x=1+x+x^2/2!+x^3/3!+x^4/4!+...+x^n/n!+o(x^n) 

比如當n=3時,

e^x=1+x+x^2/2+o(x^3)

這裡實作的方法是:sympy表達式.series(變量, 0, n)

from sympy import exp,symbols

x = symbols('x')
expr = exp(x)

expr.series(x, 0, 3)
1 + x + x**2/2 + O(x**3)