Sympy 笔记
大约 12 分钟
Sympy 笔记
默认使用 import sympy as sy
导入 Sympy
参考教程 https://docs.sympy.org/latest/index.html
表达式的基本操作
构建表达式
Sympy 中以变量符号对象为基础构建表达式
x = sy.symbol(a)
创建变量符号a
字符串, 表示创建变量的符号, 可使用空格分隔创建多个变量- 使用
x:m
则可创建x0
到xm-1
共m
个带有标号的变量 - 使用
x:m:n
则可创建x00
到xm-1n-1
共m * n
个带有标号的变量 - 变量符号与接收变量符号对象的变量不一定要同名
- 变量符号名称中没有空格即可, 因此可使用
\\theta_{1,2}
等 Latex 符号表示作为符号名称, 方便将表达式导出为 Laxte
- 使用
- 返回值为变量符号对象, 如果创建多个则为变量符号对象组成的元组
exp_res = sy.<数学函数>(exp)
exp
输入表达式, 变量符号或数值- 返回值为一个以输入表达式为变量的数学函数表达式, 如果传入数值将得到一个不含变量的表达式
- 可用的数学函数有
sin
,cos
,exp
,log
,sqrt
, 伽马函数gamma
, 阶乘factorial
等
关于表达式还有如下说明
- 表达式为 Python 对象, 可通过变量保存, 但表达式对象本身一般为不可变的, 只能通过表达式构造新的表达式
- 变量符号实际为一种特殊的表达式, 通过表达式之间的数学运算即可构造新的表达式
- 构造表达式时, Sympy 只会进行最低程度的化简, 如
- 加减法中, 直接减去已有项, 如
x + y - x = y
- 乘除法中, 直接消去公因式, 如
x * y / x = y
- 尝试将含数值的表达式转换为最简形式, 如
sy.sqrt(8 * x) = 2 * sqrt(2) * sqrt(x)
- 对于将表达式化简为特定形式见表达式化简部分
- 加减法中, 直接减去已有项, 如
表达式操作
通过表达式对象的方法可对表达式进行操作
- 变量代换
expr.subs(old, new)
/expr.subs(dicts)
old
表达式expr
中的变量符号对象或表达式 (传入表达式时将尝试从当前被修改表达式中匹配)new
用于代换的表达式或数值dicts
一个以变量符号对象为键, 代换表达式为值的字典, 通过该方法可一次代换多个参数- 返回值为一个新的表达式式, 即使所有变量都代换为数值, 得到的依然为表达式对象
- 计算表达式的值
expr.evalf(n = 15, subs = None, maxn = 100, chop = False)
n
计算结果的精度subs
一个以变量符号对象为键, 变量数值为值的字典, 表示计算表达式时各个变量的值, 如果表达式中没有变量可直接传入None
maxn
计算表达式值时允许的最大精度chop
传入False
表示不忽略任何数值, 传入数值表示允许忽略比传入值小的量
- 尝试将字符串转换为表达式
expr = sy.sympify(str)
str
表达式字符串- 返回值为转换的表达式, 如果要操作表达式中的变量应当使用
sy.symbols
创建对应名称的变量
- 将表达式封装为 Python 函数
sy.lambdify(/, args, exprs, modules)
args
单个变量符号或变量符号列表, 表示函数接收参数对应的变量exprs
用于封装的表达式对象, 当传入表达式列表时, 封装的函数将返回一个列表表示各个表达式的值modules
封装中数学函数的实现模块, 使用字符串表示, 常用的有numpy
封装中使用 Numpy 模块的数学函数, 此时可对函数传入 Numpy 数组math
封装中使用 math 模块的数学函数
打印表达式
希望 Sympy 打印表达式前, 需要先调用函数 sy.init_printing()
进行初始化
以下为常用的打印表达式函数
- 美化输出表达式
sy.pprint(expr)
expr
用于打印的表达式- 该函数将向终端打印美化的表达式输出
- 获取 Latex 形式的表达式
sy.latex(expr, *)
expr
用于打印的表达式- 该函数将返回表达式的 Latex 形式的字符串
- 通过传入参数可对样式进行设置, 以下为常用设置, 更多见官方文档
full_prec = False
是否将小数转为分数表示diff_operator = 'd'
微分算子的字体, 默认为 , 使用参数md
时表示mat_symbol_style = 'plain'
矩阵变量的字体, 默认为一般字体 , 使用参数bold
时表示\mathbf{A}
ln_notation = False
对数函数表示, 默认为 , 使用True
时为inv_trig_style = 'abbreviated'
反三角函数表示, 默认为缩写如 , 使用full
时为全称如parenthesize_super = True
当表达式被用于幂运算时, 加上括号fold_func_brackets = False
允许时省略函数的括号
其他说明
- 实用操作
expr.coeff(x, n)
提取系数x
用于分析的变量符号n
提取系数项的幂次- 返回结果为一个表达式, 即被提取的系数
- 特殊符号的表示
- 无穷
sy.oo
- 虚数单位
sy.I
- 无穷
表达式化简
通过调用 Sympy 模块的函数, 可对表达式进行进一步化简
对于一般情况, 函数 sy.simplify(expr)
将尝试使输入表达式 expr
化简为最简的形式, 并进行一些必要的函数代换如 cos(x) ** 2 + sin(x) ** 2 = 1
对于其他的化简需求, 可使用以下化简函数
多项式化简
以下化简方法以多项式为核心进行, 将其他函数视为系数
sy.expand(expr)
展开为多项式之和sy.factor(expr)
化简为多项式因式sy.collect(expr, x, *, exact = False)
以指定变量x
将表达式整理为关于该变量的各次幂与系数的多项式之和expr
被整理的表达式x
用于整理系数的变量, 表达式或表达式列表exact
为True
时, 整理时将仅提取关于指定变量的因数, 而不包含其它次幂- 如选择变量
x
将表达式整理为类似a * x ** 2 + b * x + c
的形式 (其中x
可以是表达式或表达式列表)
sy.cancel(expr)
整理为多项式之和的分式- 对于含除法的多项式可使用该函数
- 对于多项式因式的分式使用
sy.factor(expr)
即可
sy.apart(expr)
整理为多项式分式之和
其他化简函数
- 三角函数化简
以下化简方法以三角函数为核心进行 (同样适用于双曲三角函数)sy.trigsimp(expr)
将表达式中所有类型的三角函数转化为单一类型
该函数也倾向于将表达式整理到三角函数的变量内, 如sy.expand_trig(expr)
将表达式中的三角函数整理为简单变量的形式如
- 乘方表达式化简
sy.powsimp(expr)
将乘方表达式之间的乘法整理为单个乘方表达式
- 对数表达式化简
sy.logcombine(expr)
将多个对数表达式的运算整理为单个对数表达式sy.expand_log(expr)
将表达式中的对数整理为简单变量的形式
- 其他化简函数参考官方文档
- 如果希望从方程组中分离出特定变量的表达式, 应该考虑使用代数方程求解 sy.solve() 的方式实现
表达式运算
Sympy 中使用 sy.oo 表示无穷大
求导
- 计算表达式求导结果
sy.diff(expr, *symbols)
expr
被求导的表达式*symbols
按传入的符号顺序对表达式进行求导- 只传入变量符号对象时, 将按传入顺序分别求导
- 可以传入元组
(sym, n)
, 表示对符号sym
求导n
次
- 构造带求导算子的表达式
sy.Derivative(expr, *symbols)
- 参数含义同
sy.diff(expr, *symbols)
- 该函数仅构造表达式而不执行运算, 可调用表达式方法
expr.doit()
执行其中的运算
- 参数含义同
积分
- 表达式积分结果
sy.integrate(expr, **args)
expr
被积分的表达式args
按传入积分参数顺序对表达式进行多重积分- 只传入变量符号对象时, 将对该符号进行不定积分 (不包含常数 )
- 可以传入元组
(sym, lower_limit, upper_limit)
, 表示对符号sym
以上限lower_limit
与下限upper_limit
进行定积分
- 构造带积分算子的表达式
sy.Integral(expr, **args)
- 参数含义同
sy.integrate(expr, **args)
- 该函数仅构造表达式而不执行运算, 可调用表达式方法
expr.doit()
执行其中的运算
- 参数含义同
其他运算
- 表达式极限
sy.limit(e, z, z0, dir = '+')
e
被求极限的表达式z
极限变量z0
逼近的常量+
求正方向邻域的极限 (如果求负方向邻域的极限则传入-
)- 类似有
sy.Limit(e, z, z0, dir = '+')
构造带极限算子的表达式
- 泰勒级数展开
sy.series(expr, x, x0, n = 6, dir = '+')
expr
被泰勒展开的表达式x
展开变量x0
展开位置n
展开阶数dir
逼近方向- 返回值将带有该届无穷小表达式
O(x**n)
, 可对返回的表达式使用expr.removeO()
去除
- 傅里叶级数展开 见官方文档
- 有限差分 见官方文档
方程求解
代数方程
- 构造等式方程
sy.Eq(expr1, expr2)
expr1
等式左侧的表达式expr2
等式右侧的表达式- 返回等式表达式
- 注意, Sympy 中不能使用
=
或==
构造等式方程, 只能使用函数sy.Eq
当非等式的表达式用于方程求解时, 将被视为等于0
的方程
- 以集合形式表示代数方程的解
sy.solveset(/, equation, variable, domain = sy.S.Complex)
equation
用于求解的等式, 可传入等式列表表示方程组variable
方程中的待求变量, 可传放入变量对象元组, 表示多个待求变量domain
变量所在的域, 常用有sy.S.Real
表示实数域,sy.S.Complex
表示复数域- 该函数的返回值为集合, 如果有多个待求变量则返回向量的集合
- 使用该函数可用于得到代数方程解的严格表达式, 特别是多个解的情况, 但无法表示重根
- 以表达式形式表示代数方程的解
sy.solve(/, equation, variable, *, dict = False)
equation
用于求解的等式, 可传入等式列表表示方程组variable
方程中的待求变量, 可传放入变量对象元组, 表示多个待求变量 (即使仅需要从方程组中求出一个量, 也应该写入所有应消去的变量, 以此表明剩余的变量为不必消去的常量)dict
使用一个以待求变量为键, 解为值的字典表示解 (默认使用列表表示一组解, 列表的元素与传入的待求变量顺序对应)- 该函数的返回值为各个解组成的列表 (即使只有一个解或无解), 即使方程有无数解, 该函数也仅返回部分解
- 该函数得到的解依然为表达式对象
- 多项式方程求解
sy.roots(/, equation, variable)
equation
用于求解的多项式方程variable
多项式方程变量- 该函数的返回值为以方程的根为键, 方程根的重数为值的字典
- 求解方程的数值解
sy.nsolve(/, equation, x, x0 = None, *, dict = False)
equation
用于求解的等式, 可传入等式列表表示方程组x
方程中的待求变量, 可传放入变量对象元组, 表示多个待求变量x0
数值解的迭代起始值, 如果有多个起始值需要传入元组 (如果起始值为复数, 则将寻找复数解)dict
是否以字典的形式返回解, 类似sy.solve(dict = True)
常微分方程
- 常微分方程中, 未知量为关于特定变量如 的函数, 而不是一般的变量, 因此需要定义函数类型的变量对象
- 求解常微分方程的解析解
sy.dsolve(/, equation, function, *, ics = None)
equation
用于求解的常微分方程, 可传入等式元组表示方程组function
方程中的待求函数, 可传放入函数类型变量对象元组, 表示多个待求函数ics
方程组的边界条件- 默认没有给出初值条件, 则结果中将包含待定系数
Cx
, 可先定义名称为Cx
的变量符号再通过 expr.subs 带入具体值 - 可传入一个字典, 字典的键为关于函数的已知条件, 值为已知条件的值, 例如
{f.diff(t).subs(0): 1}
体现边界条件
- 默认没有给出初值条件, 则结果中将包含待定系数
- 函数的返回值为一个列表, 列表中的元素为各个待求函数的解 (等式形式), 其中函数在左侧, 函数表达式在右侧
通过等式对象的成员eq.rhs
可访问右侧的表达式
- 求解常微分方程的数值解
- 利用 sy.solve 构造 的常微分方程组
- 利用 sy.lambdify 构造 Python 函数, 其中参数
exprs
为一个列表, 对应了各阶导数的表达式 - 利用 Scipy 中的函数 scipy.integrate.solve_ivp 求出数值解