SymPy
最后修改于 2024 年 1 月 29 日
SymPy 教程介绍了如何使用 sympy 模块在 Python 中进行符号计算。这是对 SymPy 的简要介绍。
计算机代数系统 (CAS) 是一种数学软件,能够以类似于数学家和科学家传统手动计算的方式来处理数学表达式。
符号计算 处理数学对象的符号计算。数学对象被精确地表示,而不是近似表示,带有未求值的变量的数学表达式以符号形式保留。
SymPy
SymPy 是一个用于符号数学的 Python 库。它旨在成为一个功能齐全的计算机代数系统。SymPy 包含从基本符号算术到微积分、代数、离散数学和量子物理的功能。它能够以 LaTeX 格式显示结果。
$ pip install sympy
SymPy 使用 pip install sympy
命令安装。
有理数值
SymPy 提供 Rational
来处理有理数。有理数是任何可以表示为两个整数之比或分数 p/q 的数,其中 p 是分子,q 是非零分母。
#!/usr/bin/python from sympy import Rational r1 = Rational(1/10) r2 = Rational(1/10) r3 = Rational(1/10) val = (r1 + r2 + r3) * 3 print(val.evalf()) val2 = (1/10 + 1/10 + 1/10) * 3 print(val2)
该示例处理有理数。
val = (r1 + r2 + r3) * 3 print(val.evalf())
表达式是符号形式;我们使用 evalf
方法对其进行求值。
$ rational_values.py 0.900000000000000 0.9000000000000001
请注意,当不使用有理数时,输出中存在一个小错误。
SymPy pprint
pprint
用于在控制台上进行漂亮打印输出。在 Jupyter notebook 中使用 LaTeX 可以获得最佳效果。
#!/usr/bin/python from sympy import pprint, Symbol, exp, sqrt from sympy import init_printing init_printing(use_unicode=True) x = Symbol('x') a = sqrt(2) pprint(a) print(a) print("------------------------") c = (exp(x) ** 2)/2 pprint(c) print(c)
该程序美化了输出。
init_printing(use_unicode=True)
对于某些字符,我们需要启用 unicode 支持。
$ prettify.py √2 sqrt(2) ------------------------ 2⋅x ℯ ──── 2 exp(2*x)/2
这是输出。请注意,使用 Jupyter notebook 可以获得更漂亮的输出。
平方根
平方根是某个数乘以自身会得到一个指定数量的数。
#!/usr/bin/python from sympy import sqrt, pprint, Mul x = sqrt(2) y = sqrt(2) pprint(Mul(x, y, evaluate=False)) print('equals to ') print(x * y)
该程序输出一个包含平方根的表达式。
pprint(Mul(x, y, evaluate=False))
我们使用 evaluate
属性推迟乘法表达式的求值。
$ square_root.py √2⋅√2 equals to 2
SymPy 符号
符号计算处理符号,这些符号以后可以进行求值。在使用符号之前,必须在 SymPy 中定义它们。
#!/usr/bin/python # ways to define symbols from sympy import Symbol, symbols from sympy.abc import x, y expr = 2*x + 5*y print(expr) a = Symbol('a') b = Symbol('b') expr2 = a*b + a - b print(expr2) i, j = symbols('i j') expr3 = 2*i*j + i*j print(expr3)
程序展示了在 SymPy 中定义符号的三种方法。
from sympy.abc import x, y
符号可以从 sympy.abc
模块导入。它导出所有拉丁字母和希腊字母作为符号,因此我们可以方便地使用它们。
a = Symbol('a') b = Symbol('b')
它们可以使用 Symbol
定义
i, j = symbols('i j')
可以使用 symbols
方法定义多个符号。
SymPy 表达式的规范形式
SymPy 会自动将表达式转换为规范形式。SymPy 只执行低成本操作;因此,表达式可能不会简化到最简形式。
#!/usr/bin/python from sympy.abc import a, b expr = b*a + -4*a + b + a*b + 4*a + (a + b)*3 print(expr)
我们有一个包含符号 a
和 b
的表达式。该表达式可以轻松简化。
$ canonical_form.py 2*a*b + 3*a + 4*b
SymPy 展开代数表达式
使用 expand
,我们可以展开代数表达式;即,该方法尝试嵌套展开幂和乘法。
#!/usr/bin/python from sympy import expand, pprint from sympy.abc import x expr = (x + 1) ** 2 pprint(expr) print('-----------------------') print('-----------------------') expr = expand(expr) pprint(expr)
该程序展开了一个简单的表达式。
$ expand.py 2 (x + 1) ----------------------- ----------------------- 2 x + 2⋅x + 1
SymPy 简化表达式
可以使用 simplify
将表达式更改为更简单的形式。
#!/usr/bin/python from sympy import sin, cos, simplify, pprint from sympy.abc import x expr = sin(x) / cos(x) pprint(expr) print('-----------------------') expr = simplify(expr) pprint(expr)
示例将 sin(x)/sin(y)
表达式简化为 tan(x)
。
$ simplify.py sin(x) ────── cos(x) ----------------------- tan(x)
SymPy 比较表达式
SymPy 表达式使用 equals
而不是 ==
运算符进行比较。
#!/usr/bin/python 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)) # we cannot use == operator print(a == b)
该程序比较了两个表达式。
print(a.equals(b))
我们使用 equals
比较两个表达式。在应用该方法之前,SymPy 会尝试简化这些表达式。
$ expr_equality.py True False
SymPy 求值表达式
可以通过代换符号来求值表达式。
#!/usr/bin/python from sympy import pi print(pi.evalf(30))
该示例将 pi 值求值到小数点后三十位。
$ evaluating.py 3.14159265358979323846264338328
#!/usr/bin/python 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)]))
该示例通过代换 a
和 b
符号为数字来求值表达式。
$ evaluating.py 3.14159265358979323846264338328
SymPy 求解方程
方程使用 solve
或 solveset
进行求解。
#!/usr/bin/python from sympy import Symbol, solve x = Symbol('x') sol = solve(x**2 - x, x) print(sol)
该示例使用 solve
求解了一个简单的方程。
sol = solve(x**2 - x, x)
solve
的第一个参数是方程。方程以适合 SymPy 的特定形式编写;即 x**2 - x
而不是 x**2 = x
。第二个参数是要求解的符号。
$ solving.py [0, 1]
该方程有两个解:0 和 1。
或者,我们可以使用 Eq
来表示方程。
#!/usr/bin/python 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
方程。
$ solving2.py x + 1 = 4 [3]
#!/usr/bin/python from sympy.solvers import solveset from sympy import Symbol, Interval, pprint x = Symbol('x') sol = solveset(x**2 - 1, x, Interval(0, 100)) print(sol)
使用 solveset
,我们可以找到给定区间内的解。
$ solving3.py {1}
SymPy 序列
序列 是对象的枚举集合,其中允许重复。序列可以是有限的或无限的。元素的数量称为序列的长度。与集合不同,相同的元素可以在序列的不同位置出现多次。元素的顺序很重要。
#!/usr/bin/python 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)))
该示例创建了一个数字序列 1, 2, ..., 10。我们计算这些数字的总和。
$ sequence.py SeqFormula(x, (x, 1, 10)) [1, 2, 3, 4, …] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 10 55
SymPy 极限
一个 极限 是当输入(或索引)“接近”某个值时,函数(或序列)“趋近”的值。
#!/usr/bin/python from sympy import sin, limit, oo from sympy.abc import x l1 = limit(1/x, x, oo) print(l1) l2 = limit(1/x, x, 0) print(l2)
在示例中,我们有一个 1/x
函数。它有一个左极限和一个右极限。
from sympy import sin, limit, sqrt, oo
oo
表示无穷大。
l1 = limit(1/x, x, oo) print(l1)
我们计算 1/x
在 x 趋近于正无穷大时的极限。
$ limit.py 0 oo
SymPy 矩阵
在 SymPy 中,我们可以处理矩阵。矩阵是由数字或其他数学对象组成的矩形数组,可以对其进行加法和乘法等运算。
矩阵用于计算、工程或图像处理。
#!/usr/bin/python from sympy import Matrix, pprint M = Matrix([[1, 2], [3, 4], [0, 3]]) print(M) pprint(M) N = Matrix([2, 2]) print("---------------------------") print("M * N") print("---------------------------") pprint(M*N)
该示例定义了两个矩阵并相乘。
$ matrix.py Matrix([[1, 2], [3, 4], [0, 3]]) ⎡1 2⎤ ⎢ ⎥ ⎢3 4⎥ ⎢ ⎥ ⎣0 3⎦ --------------------------- M * N --------------------------- ⎡6 ⎤ ⎢ ⎥ ⎢14⎥ ⎢ ⎥ ⎣6 ⎦
SymPy 绘图
SymPy 包含一个绘图模块。它基于 Matplotlib。
#!/usr/bin/python # uses matplotlib import sympy from sympy.abc import x from sympy.plotting import plot plot(1/x)
该示例绘制了一个 1/x
函数的二维图形。
来源
以上是 SymPy 教程。
作者
列出所有 Python 教程。