简介¶
什么是符号计算?¶
符号计算处理数学对象的符号计算。这意味着数学对象是精确表示的,而不是近似表示的,并且包含未求解变量的数学表达式将以符号形式保留。
让我们举个例子。假设我们要使用内置的 Python 函数来计算平方根。我们可以这样做
>>> import math
>>> math.sqrt(9)
3.0
9 是一个完全平方数,因此我们得到了精确答案 3。但假设我们计算了一个不是完全平方数的数字的平方根
>>> math.sqrt(8)
2.82842712475
这里我们得到了一个近似结果。2.82842712475 不是 8 的精确平方根(实际上,8 的实际平方根不能用有限小数表示,因为它是一个无理数)。如果我们只关心 8 的平方根的小数形式,我们就可以完成了。
但假设我们想要更进一步。回想一下
>>> import sympy
>>> sympy.sqrt(3)
sqrt(3)
此外——而这正是我们开始看到符号计算的真正力量的地方——符号结果可以被符号简化。
>>> sympy.sqrt(8)
2*sqrt(2)
更有趣的例子¶
上面的例子开始展示了我们如何使用 SymPy 精确地操作无理数。但它远不止于此。符号计算系统(顺便说一下,也经常被称为计算机代数系统,或简称为 CAS)如 SymPy 能够计算包含变量的符号表达式。
正如我们将在后面看到的,在 SymPy 中,变量使用 symbols
定义。与许多符号操作系统不同,SymPy 中的变量必须在使用之前定义(原因将在下一节中讨论)。
让我们定义一个符号表达式,代表数学表达式
>>> from sympy import symbols
>>> x, y = symbols('x y')
>>> expr = x + 2*y
>>> expr
x + 2*y
请注意,我们写了 x + 2*y
,就像我们如果 x
和 y
是普通的 Python 变量一样。但在这种情况下,表达式不会求值为某个值,而是保留为 x + 2*y
。现在让我们玩一玩它
>>> expr + 1
x + 2*y + 1
>>> expr - x
2*y
在上面的例子中注意一些事情。当我们输入 expr - x
时,我们没有得到 x + 2*y - x
,而是只得到了 2*y
。 x
和 -x
自动相互抵消。这类似于 sqrt(8)
在上面自动变为 2*sqrt(2)
。然而,这并不总是发生在 SymPy 中。
>>> x*expr
x*(x + 2*y)
在这里,我们可能期望
>>> from sympy import expand, factor
>>> expanded_expr = expand(x*expr)
>>> expanded_expr
x**2 + 2*x*y
>>> factor(expanded_expr)
x*(x + 2*y)
符号计算的力量¶
像 SymPy 这样的符号计算系统的真正力量在于能够以符号方式进行各种计算。SymPy 可以简化表达式,计算导数、积分和极限,求解方程,处理矩阵,以及更多,并且所有这些都以符号方式进行。它包含用于绘图、打印(例如数学公式的二维漂亮打印输出,或
>>> from sympy import *
>>> x, t, z, nu = symbols('x t z nu')
这将使所有后续示例以 Unicode 字符进行漂亮打印。
>>> init_printing(use_unicode=True)
求
>>> diff(sin(x)*exp(x), x)
x x
ℯ ⋅sin(x) + ℯ ⋅cos(x)
计算
>>> integrate(exp(x)*sin(x) + exp(x)*cos(x), x)
x
ℯ ⋅sin(x)
计算
>>> integrate(sin(x**2), (x, -oo, oo))
√2⋅√π
─────
2
求
>>> limit(sin(x)/x, x, 0)
1
求解
>>> solve(x**2 - 2, x)
[-√2, √2]
求解微分方程
>>> y = Function('y')
>>> dsolve(Eq(y(t).diff(t, t) - y(t), exp(t)), y(t))
-t ⎛ t⎞ t
y(t) = C₂⋅ℯ + ⎜C₁ + ─⎟⋅ℯ
⎝ 2⎠
求
>>> Matrix([[1, 2], [2, 2]]).eigenvals()
⎧3 √17 3 √17 ⎫
⎨─ - ───: 1, ─ + ───: 1⎬
⎩2 2 2 2 ⎭
将贝塞尔函数
>>> besselj(nu, z).rewrite(jn)
√2⋅√z⋅jn(ν - 1/2, z)
────────────────────
√π
使用
>>> latex(Integral(cos(x)**2, (x, 0, pi)))
\int\limits_{0}^{\pi} \cos^{2}{\left(x \right)}\, dx
为什么选择 SymPy?¶
市面上有很多计算机代数系统。 这里 是维基百科上列出的一些系统。是什么让 SymPy 比其他系统更好呢?
首先,SymPy 完全免费。它是开源的,并根据宽松的 BSD 许可证授权,因此您可以修改源代码,甚至可以出售它(如果您愿意)。这与 Maple 或 Mathematica 等流行的商业系统形成对比,后者需要数百美元的许可证费用。
其次,SymPy 使用 Python。大多数计算机代数系统发明了自己的语言。SymPy 则没有。SymPy 完全用 Python 编写,并在 Python 中执行。这意味着如果您已经了解 Python,那么使用 SymPy 会容易得多,因为您已经知道语法(如果您不了解 Python,那么学习它也非常容易)。我们已经知道 Python 是一种设计良好、经受考验的语言。SymPy 开发人员对他们在编写数学软件方面的能力充满信心,但编程语言设计完全是另一回事。通过重用现有的语言,我们能够专注于重要的事情:数学。
另一个计算机代数系统 Sage 也使用 Python 作为其语言。但 Sage 很大,下载量超过 1 GB。SymPy 的一个优势是它很轻量级。除了相对较小之外,它也没有除 Python 之外的其他依赖项,因此它几乎可以在任何地方轻松使用。此外,Sage 和 SymPy 的目标不同。Sage 的目标是成为一个功能齐全的数学系统,并通过将所有主要的开源数学系统编译到一个系统中来实现这一点。当您在 Sage 中调用某个函数时,例如 integrate
,它会调用它包含的其中一个开源包。实际上,SymPy 包含在 Sage 中。另一方面,SymPy 的目标是成为一个独立的系统,所有功能都在 SymPy 本身中实现。
SymPy 的另一个重要特性是它可以作为库使用。许多计算机代数系统专注于在交互式环境中可用,但如果您希望自动化或扩展它们,则很难做到。使用 SymPy,您可以在交互式 Python 环境中轻松使用它,也可以在您自己的 Python 应用程序中导入它。SymPy 还提供 API,使其易于用您自己的自定义函数扩展它。