python公式_SymPy符号计算-让Python帮我们推公式

作者: 阿凯

Email: xingshunkai@qq.com

概要

像我这种粗心的小孩, 在推导一些复杂的公式(尤其是矩阵运算)的时候, 经常容易算错数, 一步推错,步步错。

万能的Python有什么方法可以帮助我们节省时间, 减少出错率呢? 有一个包叫做SymPy, 它可以帮我们自动的进行符号化计算. 所谓符号化计算的含义是指, 带入运算的不是某个具体的数值, 而是抽象的数学符号, 并且还可以帮我们将最终得到的结果进行归并简化(例如sin cos函数的合并).

这篇文章会用案例的方式, 给大家展示一下sympy的常用的功能.

安装工具包

sudo pip3 install sympy

导入工具包

import sympy as sym

from sympy import sin,cos

求解二元一次方程组

x,y = sym.symbols('x, y')

sym.solve([x + y - 1,x - y -3],[x,y])

输出日志:

{x: 2, y: -1}

测试不定积分

x = sym.symbols('x')

a = sym.Integral(cos(x))

# 积分之后的结果

a.doit()

输出日志:

equation?tex=%5Cdisplaystyle+%5Csin%7B%5Cleft%28x+%5Cright%29%7D

# 显示等式

sym.Eq(a, a.doit())

输出日志:

equation?tex=%5Cdisplaystyle+%5Cint+%5Ccos%7B%5Cleft%28x+%5Cright%29%7D%5C%2C+dx+%3D+%5Csin%7B%5Cleft%28x+%5Cright%29%7D

测试定积分

e = sym.Integral(cos(x), (x, 0, sym.pi/2))

e

输出日志:

equation?tex=%5Cdisplaystyle+%5Cint%5Climits_%7B0%7D%5E%7B%5Cfrac%7B%5Cpi%7D%7B2%7D%7D+%5Ccos%7B%5Cleft%28x+%5Cright%29%7D%5C%2C+dx

# 计算得到结果

e.doit()

输出日志:

equation?tex=%5Cdisplaystyle+1

求极限

n = sym.Symbol('n')

s = ((n+3)/(n+2))**n

#无穷为两个小写o

sym.limit(s, x, sym.oo)

输出日志:

equation?tex=%5Cdisplaystyle+%5Cleft%28%5Cfrac%7Bn+%2B+3%7D%7Bn+%2B+2%7D%5Cright%29%5E%7Bn%7D

print(sym.limit(s, x, sym.oo))

((n + 3)/(n + 2))**n

测试三角函数合并

sympy支持latex表达式

theta = symbols('theta')

a = cos(theta) * cos(theta) - sin(theta)*sin(theta)

Eq(a)

输出日志:

equation?tex=%5Cdisplaystyle+-+%5Csin%5E%7B2%7D%7B%5Cleft%28%5Ctheta+%5Cright%29%7D+%2B+%5Ccos%5E%7B2%7D%7B%5Cleft%28%5Ctheta+%5Cright%29%7D+%3D+0

三角函数简化

可以调用simplify 函数进行结果的简化, 简直是太好用了!!!!

sym.simplify(a)

输出日志:

equation?tex=%5Cdisplaystyle+%5Ccos%7B%5Cleft%282+%5Ctheta+%5Cright%29%7D

x = sym.symbols('x')

f = sym.simplify('x/x+1')

f

输出日志:

equation?tex=%5Cdisplaystyle+2

多元表达式

x, y = sym.symbols('x y')

f = (x + 2)**2 + 5*y

sym.Eq(f)

输出日志:

equation?tex=%5Cdisplaystyle+5+y+%2B+%5Cleft%28x+%2B+2%5Cright%29%5E%7B2%7D+%3D+0

传入数值

f.evalf(subs = {x:1,y:2})

输出日志:

equation?tex=%5Cdisplaystyle+19.0

拓展Latex格式

例如想要显示

equation?tex=%5Cdelta_t

delta_t = sym.symbols('delta_t')

测试行列式求解

dt = sym.symbols('delta_t')

# 定义矩阵T

T = sym.Matrix(

[[1, 0, 0, 0],

[1, dt, dt**2, dt**3],

[0, 1, 0, 0],

[0, 1, 2*dt, 3*dt**2]])

T

输出日志:

equation?tex=%5Cleft%5B%5Cbegin%7Bmatrix%7D1+%26+0+%26+0+%26+0%5C%5C1+%26+%5Cdelta_%7Bt%7D+%26+%5Cdelta_%7Bt%7D%5E%7B2%7D+%26+%5Cdelta_%7Bt%7D%5E%7B3%7D%5C%5C0+%26+1+%26+0+%26+0%5C%5C0+%26+1+%26+2+%5Cdelta_%7Bt%7D+%26+3+%5Cdelta_%7Bt%7D%5E%7B2%7D%5Cend%7Bmatrix%7D%5Cright%5D

# 计算行列式

sym.det(T)

输出日志:

equation?tex=-+%5Cdelta_%7Bt%7D%5E%7B4%7D

# 矩阵求逆

T_inverse = T.inv()

# 逆矩阵

T_inverse

输出日志:

equation?tex=%5Cleft%5B%5Cbegin%7Bmatrix%7D1+%26+0+%26+0+%26+0%5C%5C0+%26+0+%26+1+%26+0%5C%5C-+%5Cfrac%7B3%7D%7B%5Cdelta_%7Bt%7D%5E%7B2%7D%7D+%26+%5Cfrac%7B3%7D%7B%5Cdelta_%7Bt%7D%5E%7B2%7D%7D+%26+-+%5Cfrac%7B2%7D%7B%5Cdelta_%7Bt%7D%7D+%26+-+%5Cfrac%7B1%7D%7B%5Cdelta_%7Bt%7D%7D%5C%5C%5Cfrac%7B2%7D%7B%5Cdelta_%7Bt%7D%5E%7B3%7D%7D+%26+-+%5Cfrac%7B2%7D%7B%5Cdelta_%7Bt%7D%5E%7B3%7D%7D+%26+%5Cfrac%7B1%7D%7B%5Cdelta_%7Bt%7D%5E%7B2%7D%7D+%26+%5Cfrac%7B1%7D%7B%5Cdelta_%7Bt%7D%5E%7B2%7D%7D%5Cend%7Bmatrix%7D%5Cright%5D+

运动学公式自动推导

下面演示使用sympy自动推导运动学公式

定义一些符号

# 定义符号

theta_1, theta_2,theta_3, l_2, l_3 = sym.symbols('theta_1, theta_2, theta_3, l_2, l_3')

theta_1

输出日志:

equation?tex=%5Ctheta_%7B1%7D

下面是机械臂DH空间变换用到的矩阵

def RZ(theta):

'''绕Z轴旋转'''

return sym.Matrix(

[[cos(theta), -sin(theta), 0, 0],

[sin(theta), cos(theta), 0, 0],

[0, 0, 1, 0],

[0, 0, 0, 1]])

def RX(gamma):

'''绕X轴旋转'''

return sym.Matrix([

[1, 0, 0, 0],

[0, cos(gamma), -sin(gamma), 0],

[0, sin(gamma), cos(gamma), 0],

[0, 0, 0, 1]])

def DX(l):

'''绕X轴平移'''

return sym.Matrix(

[[1, 0, 0, l],

[0, 1, 0, 0],

[0, 0, 1, 0],

[0, 0, 0, 1]])

def DZ(l):

'''绕Z轴'''

return sym.Matrix(

[[1, 0, 0, 0],

[0, 1, 0, 0],

[0, 0, 1, l],

[0, 0, 0, 1]])

按照变换顺序, 依次相乘,得到总的变换矩阵

T04 = RZ(theta_1)*RX(-sym.pi/2)*RZ(theta_2)*DX(l_2)*RZ(theta_3)*DX(l_3)

公式简化, 最终得到了三自由度机械臂, 正向运动学的结果

T04 = sym.simplify(T04)

T04

输出日志:

equation?tex=%5Cleft%5B%5Cbegin%7Bmatrix%7D%5Ccos%7B%5Cleft%28%5Ctheta_%7B1%7D+%5Cright%29%7D+%5Ccos%7B%5Cleft%28%5Ctheta_%7B2%7D+%2B+%5Ctheta_%7B3%7D+%5Cright%29%7D+%26+-+%5Csin%7B%5Cleft%28%5Ctheta_%7B2%7D+%2B+%5Ctheta_%7B3%7D+%5Cright%29%7D+%5Ccos%7B%5Cleft%28%5Ctheta_%7B1%7D+%5Cright%29%7D+%26+-+%5Csin%7B%5Cleft%28%5Ctheta_%7B1%7D+%5Cright%29%7D+%26+%5Cleft%28l_%7B2%7D+%5Ccos%7B%5Cleft%28%5Ctheta_%7B2%7D+%5Cright%29%7D+%2B+l_%7B3%7D+%5Ccos%7B%5Cleft%28%5Ctheta_%7B2%7D+%2B+%5Ctheta_%7B3%7D+%5Cright%29%7D%5Cright%29+%5Ccos%7B%5Cleft%28%5Ctheta_%7B1%7D+%5Cright%29%7D%5C%5C%5Csin%7B%5Cleft%28%5Ctheta_%7B1%7D+%5Cright%29%7D+%5Ccos%7B%5Cleft%28%5Ctheta_%7B2%7D+%2B+%5Ctheta_%7B3%7D+%5Cright%29%7D+%26+-+%5Csin%7B%5Cleft%28%5Ctheta_%7B1%7D+%5Cright%29%7D+%5Csin%7B%5Cleft%28%5Ctheta_%7B2%7D+%2B+%5Ctheta_%7B3%7D+%5Cright%29%7D+%26+%5Ccos%7B%5Cleft%28%5Ctheta_%7B1%7D+%5Cright%29%7D+%26+%5Cleft%28l_%7B2%7D+%5Ccos%7B%5Cleft%28%5Ctheta_%7B2%7D+%5Cright%29%7D+%2B+l_%7B3%7D+%5Ccos%7B%5Cleft%28%5Ctheta_%7B2%7D+%2B+%5Ctheta_%7B3%7D+%5Cright%29%7D%5Cright%29+%5Csin%7B%5Cleft%28%5Ctheta_%7B1%7D+%5Cright%29%7D%5C%5C-+%5Csin%7B%5Cleft%28%5Ctheta_%7B2%7D+%2B+%5Ctheta_%7B3%7D+%5Cright%29%7D+%26+-+%5Ccos%7B%5Cleft%28%5Ctheta_%7B2%7D+%2B+%5Ctheta_%7B3%7D+%5Cright%29%7D+%26+0+%26+-+l_%7B2%7D+%5Csin%7B%5Cleft%28%5Ctheta_%7B2%7D+%5Cright%29%7D+-+l_%7B3%7D+%5Csin%7B%5Cleft%28%5Ctheta_%7B2%7D+%2B+%5Ctheta_%7B3%7D+%5Cright%29%7D%5C%5C0+%26+0+%26+0+%26+1%5Cend%7Bmatrix%7D%5Cright%5D+

导出Latex

运算得到的结果可以直接插到论文里面, 不用自己再手敲一遍latex.

直接导出结果的latex字符

sym.print_latex(T_inverse)

输出日志:

\left[\begin{matrix}1 & 0 & 0 & 0\\0 & 0 & 1 & 0\\- \frac{3}{\delta_{t}^{2}} & \frac{3}{\delta_{t}^{2}} & - \frac{2}{\delta_{t}} & - \frac{1}{\delta_{t}}\\\frac{2}{\delta_{t}^{3}} & - \frac{2}{\delta_{t}^{3}} & \frac{1}{\delta_{t}^{2}} & \frac{1}{\delta_{t}^{2}}\end{matrix}\right]

可以copy, 插入到markdown正文中

$$

这里插入刚才导出的字符串

$$

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值