Python——利用sympy模块进行数学计算

参考链接:
SymPy简易教程
SymPy库常用函数
Python sympy 模块常用功能(一)
Python科学计算库SymPy初探

简介

SymPy是一个符号计算的Python库。它的目标是成为一个全功能的计算机代数系统,同时保持代码简洁、易于理解和扩展。它完全由Python写成,不依赖于外部库。
SymPy支持符号计算、高精度计算、模式匹配、绘图、解方程、微积分、组合数学、离散 数学、几何学、概率与统计、物理学等方面的功能。(来自维基百科的描述)

基本数值类型

实数,有理数和整数
SymPy有三个内建的数值类型:实数,有理数和整数。有理数类用两个整数来表示一个有理数。分子与分母,所以Rational(1,2)代表1/2,Rational(5,2)代表5/2,等等。
分数:

from sympy import *
a = Rational(1,2)
b = Rational(2)
print(a)
print(b)

结果:

1/2
2

整数计算:

from sympy import *
a = Rational(2)**2/Rational(10)**2
b = 2**2/10**2
print(a)
print(b)

结果:

1/25
0.04

Sympy模块的特殊函数的写法

三角函数:
sin
cos
tan
反三角函数:
asin
acos
atan
指数函数:
exp()
对数函数:
Inx:log(x)
logn(x):log(x,n)

特殊的常数

E——自然常数
π——pi
e——exp(1)
limit——求极限
oo——无穷

from sympy import *
a = pi
b = pi**2
c = pi.evalf()    #evalf()函数可以用来求出表达式的浮点数
d = pi.evalf(n=3)  #evalf(n=m)是浮点数保留m个有效数字
print(a)
print(b)
print(c)

运行结果:

pi
pi**2
3.14159265358979
3.14

打印公式

from sympy import pprint, Symbol, exp, sqrt
#pprint()用于在控制台上漂亮地打印输出。 LaTeX 可以达到最佳效果。
from sympy import init_printing

init_printing(use_unicode=True)  # 对于某些字符,我们需要启用 unicode 支持
x = Symbol('x')

a = sqrt(2)
pprint(a)
print(a)

c = (exp(x) ** 2)/2
print('//----------------------//')
pprint(c)
print('//----------------------//')
print(c)

结果:

2
sqrt(2)
//----------------------//
 2⋅x
ℯ   
────
 2  
//----------------------//
exp(2*x)/2

Sympy基本使用

定义变量——Symbols函数

对比与其他的计算机代数系统,在SymPy中要明确声明符号变量:

from sympy import *
x = symbols('x')
a = x+1
print(a)

结果:

x + 1
from sympy import *
x,y,z=symbols('x y z')
crazy = symbols('unrelated')
a = crazy + 1
b = z + 1
print(a)
print(b)

结果:

unrelated + 1
z + 1

变量替换subs函数

例子:

from sympy import *
x = symbols('x')
t = symbols('t')  #定义变量
a = x + 1
b = a.subs(x, 2)
c = a.subs(x, t)
print(a)
print(b)
print(c)

结果:

x + 1
3
t + 1
from sympy import pi, exp, limit, oo
#from sympy.abc import x, y 可以从sympy.abc模块导入符号。 它将所有拉丁字母和希腊字母导出为符号,因此我们可以方便地使用它们。
from sympy.abc import x, y

a = (1 + x*y).subs(x, pi)
b = (1 + x*y).subs({
    
    x:pi, y:2})
c = (1 + x*y).subs([(x, pi), (y, 2)])
print(a)
print(b)
print(c)

结果:

pi*y + 1
1 + 2*pi
1 + 2*pi
from sympy.abc import x, y

reps = [(y, x ** 2), (x, 2)]  #x=2,y=x^2=4
a = (x + y).subs(reps)  #a=x+y=6
b = (x + y).subs(reversed(reps))  #y=2,x=x^2
print(a)
print(b)
c = (x**2 + x**4).subs(x**2, y)
d =  (x**2 + x**4).xreplace({
    
    x**2: y})
print(c)
print(d)

结果:

6
x**2 + 2
y**2 + y
x**4 + y

SymPy 规范表达形式

SymPy 会自动将表达式转换为规范形式。 SymPy 仅执行廉价操作; 因此,表达式可能无法求值为最简单的形式。

from sympy.abc import a, b
expr = b*a + -4*a + b + a*b + 4*a + (a + b)*3
print(expr)

结果:

2*a*b + 3*a + 4*b

SymPy 扩展代数表达式

使用expand(),我们可以扩展代数表达式; 即该方法尝试消除幂和乘法。

from sympy import expand
from sympy.abc import x

expr = (x + 1) ** 2
print(expr)
print(expand(expr))

结果:

(x + 1)**2
x**2 + 2*x + 1

SymPy 简化表达式

可以使用simplify()将表达式更改为更简单的形式。

from sympy import sin, cos, simplify, pprint
from sympy.abc import x,y

expr = sin(x+y) / (sin(y)*cos(x))
print(expr)
pprint(expr)
print('-----------------------')
expr = simplify(expr)
print(expr)
pprint(expr)

结果:

sin(x + y)/(sin(y)*cos(x))
  sin(x + y) 
─────────────
sin(y)⋅cos(x)
-----------------------
tan(x)/tan(y) + 1
tan(x)    
────── + 1
tan(y)    

SymPy 比较表达式

SymPy 表达式与equals()而不是==运算符进行比较。

from sympy import pprint, Symbol, sin, cos

x = Symbol('x')
a = cos(x)**2 - sin(x)**2
b = cos(2*x)

print(a.equals(b)) #  在应用该方法之前,SymPy 尝试简化表达式。
# we cannot use == operator
print(a == b)

结果:

True
False

SymPy 求值表达式

可以通过替换符号来求值表达式。

# 通过用数字替换a和b符号来求值表达式
from sympy.abc import a, b
from sympy import pprint
expr = b*a + -4*a + b + a*b + 4*a + (a + b)*3
print(expr.subs([(a, 3), (b, 2)]))

结果:

29

SymPy 求解方程

用solve()或solveset()求解方程。

from sympy import Symbol, solve
x = Symbol('x')
sol = solve(x**2 - x, x)    #x^2 - x = 0
print(sol)    #x=0 , x=1

结果:

[0, 1]

solve()的第一个参数是公式。 该公式以适合 SymPy 的特定形式编写; 即x2 - x代替x2 = x。 第二个参数是我们需要解决的符号。

或者,我们可以将Eq用于公式。

from sympy import pprint, Symbol, Eq, solve
x = Symbol('x')
eq1 = Eq(x + 1, 4)
pprint(eq1)
sol = solve(eq1, x)
print(sol)

结果:

x + 1 = 4
[3]

使用solveset(),我们找到了给定求目标区间内的解的解决方案。

from sympy.solvers import solveset
from sympy import Symbol, Interval, pprint

x = Symbol('x')

sol = solveset(x**2 - 1, x, Interval(0, 50))   #解在区间(0,50)
print(sol)
sol2 = solveset(x**2 - 1, x, Interval(-10, 50))  #解在区间(-10,50)
print(sol2)

结果:

FiniteSet(1)
FiniteSet(-1, 1)

SymPy 序列

序列是其中允许重复的对象的枚举集合。 序列可以是有限的或无限的。 元素的数量称为序列的长度。 与集合不同,同一元素可以在序列中的不同位置出现多次。 元素的顺序很重要。

from sympy import summation, sequence, pprint
from sympy.abc import x

s = sequence(x, (x, 1, 10))
print(s)
pprint(s)
print(list(s))
print(s.length)
print(summation(s.formula, (x, s.start, s.stop)))
print(sum(list(s)))

结果:

SeqFormula(x, (x, 1, 10))
[1, 2, 3, 4,]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
10
55
55

SymPy 极限

极限是函数(或序列)“接近”作为输入(或索引)“接近”某个值的值。

from sympy import sin, limit, oo
from sympy.abc import x

l1 = limit(1/x, x, oo)
print(l1)

l2 = limit((1+x)**(1/x), x, 0)
print(l2)

结果:

0
E

SymPy 矩阵

在 SymPy 中,我们可以使用矩阵。 矩阵是数字或其他数学对象的矩形数组,为其定义了运算(例如加法和乘法)。

矩阵用于计算,工程或图像处理。

from sympy import Matrix, pprint
N = Matrix([2, 2])
pprint(N)
M = Matrix([[2],[2]])
pprint(M)

结果:

2⎤
⎢ ⎥
⎣2⎦
⎡2⎤
⎢ ⎥
⎣2

矩阵计算:

from sympy import Matrix, pprint

M = Matrix([[1, 2], [3, 4], [0, 3]])
pprint(M)
N = Matrix([2, 2])
pprint(N)
print("---------------------------")
print(M*N)
print("---------------------------")
pprint(M*N)

结果:

1  2⎤
⎢    ⎥
⎢3  4⎥
⎢    ⎥
⎣0  3⎦
⎡2⎤
⎢ ⎥
⎣2---------------------------
Matrix([[6], [14], [6]])
---------------------------6 ⎤
⎢  ⎥
⎢14⎥
⎢  ⎥
⎣6

SymPy 绘图

SymPy 包含用于绘图的模块。 它基于 Matplotlib 构建。

from sympy import sin
from sympy.abc import x
from sympy.plotting import plot
plot(sin(x))

结果:
在这里插入图片描述

函数的求导

函数求导要用到sympy中的diff
diff的基本用法
diff(func,x,n)
其中:

  • func是要求导的函数
  • x是要对其求导的变量
  • n是可选的,表示求n阶导数,默认为1阶导数

注意】在用diff进行求导之前,需要用symbols函数定义变量
1、一元函数一阶导数

from sympy import diff
from sympy import symbols
x = symbols("x")
a = diff(x**4,x)
print(a)

结果:

4*x**3

2、一元函数多阶求导

from sympy import diff
from sympy import symbols
def func(x):
    return x**4
x = symbols("x")
print(diff(func(x),x,3))

结果:

24*x

3、对多变量函数求偏导

from sympy import diff
from sympy import symbols
def func(x,y):
    return x**4*y+x*y**3
x,y = symbols("x,y")
print(diff(func(x,y),x))  #函数对x求偏导
print(diff(func(x,y),y))  #函数对y求偏导
print(diff(func(x,y),x,y))  #函数对x先求偏导,然后对y求偏导

结果:

4*x**3*y + y**3
x**4 + 3*x*y**2
4*x**3 + 3*y**2

4、将导数带入具体的值求某一点处的导数

from sympy import diff
from sympy import symbols
x = symbols("x")
print(diff(x**4,x).subs(x,2))   # 表示将x = 2,带入导函数4*x**3中

结果:

32

求不定积分

from sympy import *
x = symbols('x')
expr = exp(x) * sin(x) + exp(x) * cos(x)
print(integrate(expr, x))    #integrate是积分的意思
pprint(integrate(expr, x))  

结果:

exp(x)*sin(x)
 x       
ℯ ⋅sin(x)

求定积分

import sympy
from sympy import *
x = symbols('x')
expr = exp(x) * sin(x) + exp(x) * cos(x)
print(integrate(expr, x, (x,-oo,oo)))
pprint(integrate(expr, x, (x,-oo,oo)))
a = sympy.log(x)
print(integrate(a, x, (x,1,2)))
pprint(integrate(a, x, (x,1,2)))
print(integrate(a, x, (x,1,oo)))
pprint(integrate(a, x, (x,1,oo)))

结果:

AccumBounds(-oo, oo)
<-,>
-9/4 + 2*log(2)
-9/4 + 2⋅log(2)
oo
∞

求微分方程的解

from sympy import *
y = Function('y')
t = Symbol('t')
pprint(y(t).diff(t))    #y'
pprint(y(t).diff(t,t))   #y''
sol = dsolve(Eq(y(t).diff(t,t) - y(t), exp(t)), y(t))  #求解y''-y=e^t
print(sol)

结果:

d       
──(y(t))
dt      
  2      
 d       
───(y(t))
  2      
dt       
Eq(y(t), C2*exp(-t) + (C1 + t/2)*exp(t))

打印latex公式

from sympy import *
x = symbols('x')
expr = cos(x)**2
pprint(Integral(expr, (x, 0, pi)))
print('//---------------------------//')
print(latex(Integral(expr, (x, 0, pi))))

结果:

π           
⌠           
⎮    2      
⎮ cos (x) dx
⌡           
0           
//---------------------------//
\int\limits_{
    
    0}^{
    
    \pi} \cos^{
    
    2}{
    
    \left(x \right)}\, dx

因式分解

from sympy import *
from sympy.abc import x,y,z

print(factor(x**3 - x**2 + x - 1))
print(factor(x**2*z + 4*x*y*z + 4*y**2*z))

结果:

(x - 1)*(x**2 + 1)
z*(x + 2*y)**2

降幂排列

from sympy import *
from sympy.abc import x,y,z

expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3
print(collect(expr, x))   #按x降幂排列
print(collect(expr, x).coeff(x,2))    #和 coeff搭配使用,可以求n次项系数, 这里就是求x^2项的系数

结果:

x**3 + x**2*(2 - z) + x*(y + 1) - 3
2 - z

约分

from sympy import *
from sympy.abc import x

print(cancel((x**2 + 2*x + 1)/(x**2 + x)))

结果:

(x + 1)/x

三角函数化简

from sympy import *
from sympy.abc import x

print(trigsimp(sin(x)**4 - 2*cos(x)**2*sin(x)**2 + cos(x)**4))
print(trigsimp(cosh(x)**2 + sinh(x)**2))    #可用于双曲函数化简

结果:

cos(4*x)/2 + 1/2
cosh(2*x)

三角函数展开

from sympy import *
from sympy.abc import x,y

print(expand_trig(sin(x + y)))
print(expand_trig(tan(2*x)))    

结果:

sin(x)*cos(y) + sin(y)*cos(x)
2*tan(x)/(1 - tan(x)**2)

特殊函数

factorial(n) #阶乘
binomial(n, k) #二项分布函数
gamma(x) #伽玛函数(Gamma函数),也叫欧拉第二积分

伽玛函数(Gamma函数),也叫欧拉第二积分,是阶乘函数在实数与复数上扩展的一类函数。该函数在分析学、概率论、偏微分方程和组合数学中有重要的应用。与之有密切联系的函数是贝塔函数,也叫第一类欧拉积分,可以用来快速计算同伽马函数形式相类似的积分。
伽玛函数(Gamma Function)作为阶乘的延拓,是定义在复数范围内的亚纯函数,通常写成Γ(x)
当函数的变量是正整数时,函数的值就是前一个整数的阶乘,或者说Γ(n+1)=n!
Γ(x+1)=xΓ(x),Γ⑴=1,Γ(1/2)=√π,对正整数n,有Γ(n+1)=n!,Γ(1-x)Γ(x)=π/sin(πx)
对于x>0,伽马函数是严格凸函数。
伽马函数是亚纯函数,在复平面上,除了零和负整数点以外,它全部解析,而伽马函数在-k处的留数为(-1)^k/k!

from sympy import *

print(factorial(5))
print(binomial(20, 1/3))
print(gamma(5))

结果:

120
3.05661679604108
24

方程(组)求解

from sympy import *
from sympy.abc import x,y

print(solve(x**3 - 4*x**2 - 3*x + 18))
print(roots(x**3 - 4*x**2 - 3*x + 18))  #如果要求多重根重复次数可以用roots
print(solve([x - y + 2, x + y - 3], [x, y]))  #求解方程组

结果:

[-2, 3]  #如果有重根仅显示一个
{
    
    -2: 1, 3: 2}   #表示 -2 是1重根,3 是2重根
#因此x**3 - 4*x**2 - 3*x + 18 = 0 的解:-2,3,3
{
    
    x: 1/2, y: 5/2}

猜你喜欢

转载自blog.csdn.net/weixin_48615832/article/details/109170199