使用Python的SymPy库解决数学运算问题
来源:互联网 发布:类似于知乎的app 编辑:程序博客网 时间:2024/06/13 02:19
SymPy一个用于符号型数学计算(symbolic mathematics)的Python库。它旨在成为一个功能齐全的计算机代数系统(Computer Algebra System,CAS),同时保持代码简洁、易于理解和扩展。SymPy完全是用Python写的,并不需要外部的库。
本文选择Sympy库的原因在于:
- 免费:该库基于BSD开源许可,免费(free as in beer)且开源(free as in speech);
- 基于Python:该库完全是用Python写就,并以Python作为该库操作语言;
- 轻量级:为了使Sympy简单易用,该库仅基于mpmath库(一个纯Python库,用于浮点运算);
- 灵活性:除了用作交互工具,还可插入其他应用或软件拓展功能中。
具体说来,如果x与y未曾赋值,那么下列语句就会报错
#测试语句print(x+y)
而符号运算则不同,符号运算多用于公式推导,不需要赋值,此时使用Sympy进行符号运算便具有方便快捷的优势,如下述语句便不会报错。
#测试语句x=Symbol('x')y=Symbol('y')print(x+y)
2 SymPy库解决数学运算问题实现
2.1 求解线性方程组
(1)
解方程的功能主要是使用Sympy中solve函数实现。以式(1)为例,求解过程如下:
(1) 符号表示
SymPy库中使用Symbol函数定义符号变量,
from sympy import *x=Symbol('x')y=Symbol('y')#或者用如下语句x,y=Symbol('x y')#第二个用空格隔开
(2)方程表示
使用代码表示数学符号与手写体的数学运算符号存在一定的差异,下面列举常用的运算符:
- 加号
- 加号 +
- 减号 -
- 除号 /
- 乘号 *
- 指数 **
- 对数 log()
- e的指数次幂 exp()
对于长的表达式,如果不确定运算符的优先级,可以加入小括号提升其优先级。由于需要将表达式都转化成右端等于0,这里把常数3和7移到等式左边。题目中表达式可表示为:
2*x-y-3=03*x+y-7=0
(3)使用Solve函数解方程
在使用Solve函数解方程之前,我们先来看一下Solve函数的定义。Solve函数的第一个参数是要解的方程,要求右端等于0,第二个参数是未知数。
对于式(1)的求解,代码如下:
from sympy import *x = Symbol('x')y = Symbol('y')print(solve([2*x-y-3,3*x+y-7],[x,y]))
求出的结果如下图所示:
2.2 求解微积分问题
2.2.1 求解极限问题
在2.1中通过一个简单的二元一次方程组求解熟悉了该库求解数学问题的基本过程,下面本文通过示例,讲解使用SymPy库求解微积分的过程。
(2)
求解式(2)所示的极限问题,需要用到limit函数求极限。
(1)符号及方程表示
引入Sympy库并定义n为符号变量与2.1中一致。
from sympy import *n = Symbol('n')s = ((n+3)/(n+2))**n
(2)利用limit函数求极限首先我们介绍limit函数的调用格式:limit(e, z, z0, dir='+'),e为任意表达式,表示求取e(z)在点z0处的极限,dir='+'表示取右极限,die='-'则表示取左极限。则上式的求解代码可表示如下:
from sympy import *n = Symbol('n')s = ((n+3)/(n+2))**nprint(limit(s,n,oo)) #无穷的表示方法是两个小写的字母o
2.2.2 求解定积分
(1)符号表示
from sympy import *t = Symbol(t)x = Symbol(x)
(2)方程表示
m = integrate(sin(t)/(pi-t),(t,0,x))n = integrate(m,(x,0,pi))
完整代码如下:from sympy import *t = Symbol(t)x = Symbol(x)m = integrate(sin(t)/(pi-t),(t,0,x))n = integrate(m,(x,0,pi))print(n)
2.2.3 求解微分问题
如求取的通解
(1)符号表示
这里与之前不同的是增加了函数的表示(用f(x)表示y),即例题中的y还有微分表示
from sympy import *f = Function('f')x = Symbol('x')
y'的表示方法由以下代码组成
diff(f(x),x)
这里对diff函数稍作介绍:
上面是求一阶导的方法,求解高阶导的方法如下所示:
>>> diff(x**3,x)3*x**2>>> diff(x**3,x,1)3*x**2>>> diff(x**3,x,2)6*x>>> diff(x**3,x,3)6>>> diff(x**3,x,4)0
即改变第三个参数即可。
下面继续我们的解题过程。
#左端diff(f(x),x)#看一下print(diff(f(x),x))#result#d#--(f(x))#dx#右端2*f(x)*x
用dsolve函数解微分方程
dsolve函数是用来解决微分方程(differential equation)的函数。
函数的一个用法为:
dsolve(eq, f(x))
第一个参数为微分方程(要先将等式移项为右端为0的形式)。第二个参数为要解的函数(在微分方程中)
举个例子:
>>> from sympy import *>>> f = Function('f')>>> x = Symbol('x')>>> pprint(2*x-diff(f(x),x)) d2*x - --(f(x)) dx>>> dsolve(2*x - diff(f(x),x), f(x))#result#Eq(f(x), C1 + x**2)
这样,我们可以将我们要解的题目,用以下代码表示。
dsolve(diff(f(x),x) - 2*f(x)*x, f(x))
结果为:
Eq(f(x), C1*exp(x**2))#即f(x) = C1*exp(x**2)
对比答案可以发现正确。
完整代码:
from sympy import *f = function('f')x = Symbol('x')print(dsolve(diff(f(x),x)-2*f(x)*x,f(x))
2.2.4 矩阵化简
平时线性代数问题中我们会遇到化简问题,虽然不算难,但着实麻烦。而且,出一点错就会导致
结果出错。不过好运的是SymPy提供了相关的支持。
例题:
符号表示与矩阵表示
from sympy import *x1,x2,x3 = symbols('x1 x2 x3')a11,a12,a13,a22,a23,a33 = symbols('a11 a12 a13 a22 a23 a33')m = Matrix([[x1,x2,x3]])n = Matrix([[a11,a12,a13],[a12,a22,a23],[a13,a23,a33]])v = Matrix([[x1],[x2],[x3]])
注意m的表示,需要有两个中括号
化简实现
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)]])
使用
f = m * n * vprint f[0]
可以进一步得到化简后的式子
也许你要问我要化简后在计算怎么办?下面我就举个例子。
如果上式中x1,x2,x3均等于1,则可这样代入。
from sympy import *x1,x2,x3 = symbols('x1 x2 x3')a11,a12,a13,a22,a23,a33 = symbols('a11 a12 a13 a22 a23 a33')m = Matrix([[x1, x2, x3]])n = Matrix([[a11, a12, a13], [a12, a22, a23], [a13, a23, a33]])v = Matrix([[x1], [x2], [x3]])f = m * n * vprint f[0].subs({x1:1, x2:1, x3:1})
可得
a11 + 2*a12 + 2*a13 + a22 + 2*a23 + a33
- 使用Python的SymPy库解决数学运算问题
- Sympy的使用
- sympy —— Python 符号运算
- python-sympy
- python使用pip安装SciPy、SymPy、matplotlib
- python的数学运算符
- python sympy包符号运算进行定积分计算
- 利用Sympy做数学
- 使用模运算解决的问题
- python科学计算库Sympy指南
- 利用python来解决 小鸡,公鸡,母鸡的数学问题
- python解决没有三目运算符(?:)的问题
- Python基础及其数学库的使用
- Python 数学运算
- Python 数学运算
- python中数学运算
- python基础-数学运算
- Python 符号计算的瑞士军刀——SymPy
- android 程序全局自动捕获异常 专制系统奔溃,异常退出无法找到原因的问题
- php 安装 sqlsrv pdo_sqlsrv拓展
- Light Bulb ZOJ
- 基于FTRL的在线CTR预测算法
- linux配置Tomcat
- 使用Python的SymPy库解决数学运算问题
- cuda矩阵之心得
- 【拉格朗日求自然数幂和】cf622F
- springboot—restful风格
- Linux 之内核态与用户态
- JavaScript原型
- CTF中的编码与加密题
- 动态规划5:找零钱问题
- 简单的c++垃圾回收器