SymPy 是Python的数学符号计算库,用它可以进行数学公式的符号推导。
为了调用方便,下面所有的实例程序都假设事先从 sympy 库导入了所有内容:
from sympy import *
数学中有一个著名的公式: eiπ + 1 = 0 ,叫做欧拉恒等式。
其中e是自然指数的底,i是虚数单位, π 是圆周率。
此公式被誉为数学最奇妙的公式,它将5个基本数学常数用加法、乘法和幂运算联系起来。
我曾经本以为用编程语言是没法表达这种公式的,现在看来果然是图样图森破。
下面用 SymPy 验证一下这个公式。
载入的符号中,E 表示自然指数的底, I 表示虚数单位, pi 表示圆周率,
因此上述的公式可以直接如下计算:
from sympy import *
E**(I*pi)+1
欧拉恒等式可以下面的公式进行计算:
e^ix = cos(x) + i sin (x)
为了用 SymPy 求证上面的公式,我们需要引入变量 x 。
在 SymPy 中,数学符号是 Symbol 类的对象,
因此必须先创建之后才能使用:
x = Symbol('x')
expand 函数可以将公式展开,我们用它来展开 E**(I*pi) 试试看:
expand( E**(I*x) )
没有成功,只是换了一种写法而已。这里的 exp 不是 math.exp 或者 numpy.exp,而是sympy.exp ,
它是一个类,用来表述自然指数函数。
expand 函数有关键字参数 complex ,当它为 True 时,expand 将把公式分为实数和虚数两个部分:
expand(exp(I*x), complex=True)
这次得到的结果相当复杂,其中 sin, cos, re, im都是 sympy 定义的类,
re 表示取实数部分,im 表示取虚数部分。
显然这里的运算将符号x当作复数了。
为了指定符号x必须是实数,我们需要如下重新定义符号 x :
x = Symbol("x", real=True)
expand(exp(I*x), complex=True)
终于得到了我们需要的公式。那么如何证明它呢。我们可以用泰勒多项式展开:
tmp = series(exp(I*x), x, 0, 10)
pprint(tmp)
2 3 4 5 6 7 8 9
x ⅈ⋅x x ⅈ⋅x x ⅈ⋅x x ⅈ⋅x ⎛ 10⎞
1 + ⅈ⋅x - ── - ──── + ── + ──── - ─── - ──── + ───── + ────── + O⎝x ⎠
2 6 24 120 720 5040 40320 362880
series 是泰勒展开函数,pprint 将公式用更好看的格式打印出来。
下面分别获得 tmp 的实部和虚部,分别和 cos(x) 和 sin(x) 的展开公式进行比较:
pprint(re(tmp))
8 6 4 2 x x x x ⎛ ⎛ 10⎞⎞ ───── - ─── + ── - ── + re⎝O⎝x ⎠⎠ + 1 40320 720 24 2
pprint(series( cos(x), x, 0, 10) )
2 4 6 8
x x x x ⎛ 10⎞
1 - ── + ── - ─── + ───── + O⎝x ⎠
2 24 720 40320
pprint(im(tmp))
9 7 5 3 x x x x ⎛ ⎛ 10⎞⎞ ────── - ──── + ─── - ── + x + im⎝O⎝x ⎠⎠ 362880 5040 120 6
pprint(series(sin(x), x, 0, 10))
3 5 7 9
x x x x ⎛ 10⎞
x - ── + ─── - ──── + ────── + O⎝x ⎠
6 120 5040 362880