SymPy一个用于符号型数学计算(symbolic mathematics)的Python库。它旨在成为一个功能齐全的计算机代数系统(Computer Algebra System,CAS),同时保持代码简洁、易于理解和扩展。SymPy完全是用Python写的,并不需要外部的库。

基础语法

符号表示

SymPy库中使用Symbol函数定义符号变量

  1. from sympy import *
  2. x=Symbol('x')
  3. y=Symbol('y')
  4. # ------------------
  5. x, y=Symbol('x y') # 第二个用空格隔开

方程表示

使用代码表示数学符号与手写体的数学运算符号存在一定的差异,对于长的表达式,如果不确定运算符的优先级,可以加入小括号提升其优先级。下面列举常用的运算符:

  • 加号 +
  • 减号 -
  • 除号 /
  • 乘号 *
  • 指数 **
  • 对数 log()
  • e的指数次幂 exp()

符号的输出设置

在sympy里进行符号运算之前,必须先定义sympy的符号,这样sympy才能识别该符号。
.init_printing(use_latex=True)开启时,运行时输出的是LaTeX的格式。
使用:latex()函数,同样返回LaTeX的格式。

  1. import sympy
  2. x, y, z = sympy.Symbol('x y z') # 符号化变量
  3. sympy.init_printing(use_latex=True) # 输出设置
  4. print("x:", type(x))
  5. print("y:", type(y))
  6. print(x ** 2 + y + z)
  7. print(sympy.latex(x ** 2 + y + z))
  8. # output:
  9. # x: <class 'sympy.core.symbol.Symbol'>
  10. # y: <class 'sympy.core.symbol.Symbol'>
  11. # x**2 + y + z
  12. # x^{2} + y + z

替换符号

sub是Substitution的简称,也就是替换。语法是:expr.sub(old, new)其有两个作用:

  1. 数值替换,用数值替换符号,进行带入计算。
  2. 符号替换,用一些符号替换符号。 ```python import sympy

x, y, z = sympy.symbols(‘x y z’) expr = x ** 2 + 1

数值替换

result = expr.subs(x, 2) print(“原式:”, expr) print(“数值计算:”, result)

符号替换

new_expr = expr.subs(x, y + z) print(“符号替换:”, new_expr)

output

原式: x**2 + 1

数值计算: 5

符号替换: (y + z)**2 + 1

  1. PS
  2. - `subs()`函数不改变原表达式,并且返回一个修改的表达式。
  3. - 当需要替换多个表达式时,可以在subs()里使用列表。如:`subs([(x,2), (y, 3), (z, 4)])`,表示:将x替换成2y替换成3z替换成4
  4. <a name="HSw6y"></a>
  5. ## 将字符串变为sympy的表达式
  6. ```python
  7. import sympy
  8. string = "x**2+2*y + z/2"
  9. expr = sympy.sympify(string) # 转化
  10. print("类型:", type(expr))
  11. print("表达式:", expr)
  12. # output
  13. # 类型: <class 'sympy.core.add.Add'>
  14. # 表达式: x**2 + 2*y + z/2

PS:不要混淆了sympify()函数与 simplify()函数,前者是转化,后者是简化。

数值计算

相当于python自带的eval()函数,只是进行的是float浮点数运算。

(1)对于数值表达式的运算:

  1. import sympy
  2. expr = sympy.sqrt(8)
  3. result = expr.evalf() # 进行计算
  4. print(result)
  5. # output
  6. # 2.82842712474619

(2)对于符号表达式的运算:

对于表达式常用的是:.evalf(subs={x: 2.4})

  1. import sympy
  2. x = sympy.Symbol('x')
  3. expr = x**2+3
  4. result = expr.evalf(subs={x: 2})
  5. print(result)
  6. # output
  7. # 7.00000000000000

自定义表达式

该函数有点类似于lambda(),用于自己构造一个函数表达。

  1. import sympy
  2. import numpy as np
  3. x = sympy.Symbol('x')
  4. a = np.arange(10)
  5. expr = x ** 2
  6. f = sympy.lambdify(x, expr, "numpy") # 构造自己的函数
  7. print(f(a))
  8. # output
  9. # [ 0 1 4 9 16 25 36 49 64 81]

解方程

解方程的功能主要是使用Sympy中solve函数实现。Solve函数的第一个参数是要解的方程,要求右端等于0,第二个参数是未知数。

  1. import sympy
  2. x = sympy.symbols("x") # 申明未知数"x"
  3. a = sympy.solve([x + (1 / 5) * x - 240], [x]) # 写入需要解的方程体
  4. print(a)

在写入方程的时候,将等号右边的数移到了等号左边,然后将等号丢弃,最后变成了一个式子。(注意移动过程中的变号)

解方程组:

  1. import sympy
  2. x, y = sympy.symbols("x y")
  3. a = sympy.solve([3 * x - 2 * y - 3, x + 2 * y - 5], [x, y])
  4. print(a)

解分式方程:

  1. import sympy
  2. x, y = sympy.symbols("x y")
  3. a = sympy.solve([((x + 1) / x + 1 / (x - 2)) - 1], [x])
  4. print(a)

巧算代数式,比如下面这道题:
image.png

  1. import sympy
  2. x, y = sympy.symbols("x y")
  3. a = sympy.solve([x + y - 0.2, x + 3 * y - 1], [x, y])
  4. x, y = a[x], a[y]
  5. re = x ** 2 + 4 * x * y + 4 * y ** 2
  6. print(re)

求极限

需要用到limit()函数求极限。

  1. import sympy
  2. n = sympy.symbols("n")
  3. s = ((n + 3) / (n + 2)) ** n
  4. a = sympy.limit(s, n, "oo")
  5. print(a)

无穷的表示方法是两个小写的字母o,即”oo“或”-oo“。

求不定积分

用法其实和上面都一样。

  1. import sympy
  2. x = sympy.symbols("x")
  3. a = sympy.integrate("x**2", x)
  4. print(a)

integrate是不定积分运算函数。这个函数有两个参数:

  • 前面一个参数是需要计算不定积分的函数
  • 后面的参数是以谁为参数计算不定积分。

求定积分

  1. import sympy
  2. t = sympy.Symbol("t")
  3. x = sympy.Symbol("x")
  4. m = sympy.integrate("sin(t) / (pi - t)", (t, 0, x))
  5. n = sympy.integrate(m, (x, 0, "pi"))
  6. print(n)

求解微分

diff函数:diff(f(x), x, k)。k表示求k阶导的意思。

  1. import sympy
  2. f = sympy.Function("f")
  3. x = sympy.symbols("x")
  4. a = sympy.diff(x**3, x, 2)
  5. print(a)

解微分方程

dsolve函数是用来解决微分方程的函数。函数的一个用法为:dsolve(eq, f(x))

  • 第一个参数为微分方程(要先将等式移项为右端为0的形式)
  • 第二个参数为要解的函数(在微分方程中)
    1. import sympy
    2. f = sympy.Function("f")
    3. x = sympy.symbols("x")
    4. a = 2 * x - sympy.diff(f(x), x)
    5. b = sympy.dsolve(a, f(x))
    6. print(b) # Eq(f(x), C1 + x**2)
    最后的答案Eq(f(x), C1*exp(x**2))表示:f(x) = C1*exp(x**2)

矩阵化简

  1. import sympy
  2. x1, x2, x3 = sympy.symbols('x1 x2 x3')
  3. a11, a12, a13, a22, a23, a33 = sympy.symbols('a11 a12 a13 a22 a23 a33')
  4. m = sympy.Matrix([[x1, x2, x3]]) # 注意有两个括号
  5. n = sympy.Matrix([[a11, a12, a13], [a12, a22, a23], [a13, a23, a33]])
  6. v = sympy.Matrix([[x1], [x2], [x3]])
  7. print(m * n * v) # Matrix([[x1*(a11*x1 + a12*x2 + a13*x3) + x2*(a12*x1 + a22*x2 + a23*x3) + x3*(a13*x1 + a23*x2 + a33*x3)]])

如果上式中x1,x2,x3均等于1,则可这样代入:

  1. import sympy
  2. x1, x2, x3 = sympy.symbols('x1 x2 x3')
  3. a11, a12, a13, a22, a23, a33 = sympy.symbols('a11 a12 a13 a22 a23 a33')
  4. m = sympy.Matrix([[x1, x2, x3]]) # 注意有两个括号
  5. n = sympy.Matrix([[a11, a12, a13], [a12, a22, a23], [a13, a23, a33]])
  6. v = sympy.Matrix([[x1], [x2], [x3]])
  7. f = m * n * v
  8. print(f[0].subs({x1: 1, x2: 1, x3: 1})) # a11 + 2*a12 + 2*a13 + a22 + 2*a23 + a33