SymPy学习笔记(一)安装与基本使用
简介
SymPy 是一个开源的符号计算Python库,SymPy采用了宽松的BSD开源协议,并且完全免费。它的目标是成为一个全功能的计算机代数系统(CAS),同时保持代码尽可能简单,以便于理解和扩展。
本学习笔记参考官方的教程:https://docs.sympy.org/latest/tutorials
安装
如果你使用Anacoda,无需安装,Anacoda内置了SymPy。
如果你使用pip:
1 | pip install sympy |
前置芝士
会Python就行。数学水平因人而异,根据自己的需要选用相应的功能。
什么是符号计算?
前面提到,SymPy是一个 符号计算 库,那么什么是符号计算。符号计算(Symbolic Computation),就是在计算机上用符号精确表示数学对象,而不是得到一个近似的数值解。
看一个例子:
1 | >>>import math |
Python的math库给出的计算的结果是,然而实际上,这只是的一个近似值,我们知道,它的精确值是不能用有限的小数表示的。
而在SymPy中:
1 | from sympy import * |
SymPy给我们的结果是,这才是一个精确的化简的结果。在SymPy中,非完全平方数的平方根默认会被保留。
定义符号与计算
在SymPy中,符号需要在使用前用Symbol()
或symbols()
来定义:
1 | a = Symbol('a') |
最好将变量名设置得与符号名一致,方便记忆和使用。除非符号中包含了Python不允许的符号,或者符号名太长,想使用一个短一点的变量名来表示。
SymPy支持直接使用+
、-
、*
、/
、**
来操作这些符号。
1 | >>> x, y = symbols("x y") |
输入x * expr
你会发现SymPy并没有为我们展开表达式为x**2 + 2*x*y
,而是保留了x*(x + 2*y)
的形式。因为因式分解是SymPy默认的化简操作,你也可以利用expand
来展开,用factor
来分解。
1 | >>> expand(x * expr) |
SymPy计算出了展开的结果,和因式分解的结果。
输出
可以通过调整一些选项改变SymPy输出的格式。
用init_printing(use_unicode=True)
可以允许SymPy使用Unicode输出。
计算
1 | >>> init_printing(use_unicode=False) |
第一个输出中SymPy使用了字符画的方式画出\sqrt \quad,使用了pi
表示。第二个输出使用了Unicode字符“√”和“π”。
SymPy还可以使用:
1 | >>> latex(Integral(cos(x)**2, (x, 0, pi))) |
将\int\limits_{0}^{\pi} \cos^{2}{\left(x \right)}\, dx
使用任意一个编译器编译,就可以得到下面这样漂亮的结果:
符号的替换
用subs()
,但注意subs()
并不改变原表达式。
1 | >>> expr = cos(x) + 1 |
也可以替换数字,进行在某一点求值的操作。
1 | >>> expr = sin(2*x) + cos(2*x) |
也可以替换多个符号
1 | >>> expr = x**3 + 4*x*y - z |
字符串转表达式
用sympify()
(不是symplify(
)
1 | >>> str_expr = "x**2 + 3*x - 1/2" |
表达式转浮点数
用evalf()
1 | >>> expr = sqrt(8) |
默认情况下,会给出15位的精度,但是也可以指定所需要的精度
1 | expr.evalf(100) |
如果想要用subs()
进行单点求值后再用evalf()
进行数值估计,用expr.evalf(subs={<Symbol>: <Value>})
是比expr.subs(<Symbol>, <Value>).evalf()
更推荐的方法。因为这样会使计算更高效且稳定。
1 | >>> expr = cos(2*x) |
假如指定了chop=True
,SymPy会自动移除小于期望精度的舍入误差
1 | >>> one = cos(1)**2 + sin(1)**2 |
多点求值
使用SymPy对表达式做多点的求值(比如成千上万点后)是比较慢的。如果有这种需求,可以对表达式lambdify()
后交给其他库处理(比如NumPy或SciPy)
1 | >>> import numpy |
lambdify()
将一个SymPy表达式转换成一个计算表达式在某点的值的函数,以便于使用其他库进行计算。