Sympy入门之微积分基本运算
Sympy是一个专注于符号数学计算的数学工具,使得用户可以轻松地进行复杂的符号运算,如求解方程、求导数、积分、级数展开、矩阵运算等。
获取方式
pip install -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple sympy
注:本文所使用python环境为jupyter notebook,所有代码只有在jupyter ipynb环境中才可以正确输出
基本四则运算
对于基本四则运算而言,我们只需要在定义变量后,使用python中的四则运算符对变量进行组合即可实现。
import sympy as sp
x,y=sp.symbols('x y')
expressions1=x+y**2
expressions2=sp.sqrt(x)+sp.sqrt(y)
#doit()方法用来将值带入后尽可能的保留原式(当表达式中含有根式,超越数(π,e),以及未赋值的变量时)
#evalf()方法用来将值带入计算
result1=sp.Subs(expressions1,(x,y),(sp.pi,sp.E)).doit()#π+e^2
result2=sp.Subs(expressions2,(x,y),(2,y)).doit()#只将x带入,y保留
result3=sp.Subs(expressions1,(x,y),(1,5)).evalf()#计算1^2+5^2
display(result1)
display(result2)
display(result3)
结果:
说明
在许多运算中Sympy都提供了以该运算英文名称为名的一个类与函数,这个类主要用来表示未计算的运算表达式,函数则用来计算值该运算结果下的值。
极限运算
在极限运算中,sympy提供了一个名为 sp.limit()函数可以用来直接求解函数极限。
sp.limit()函数参数详解:
e | 极限表达式,使用定义过的变量书写 |
z | 极限自变量 |
z0 | 极限自变量趋于的值 |
dir | 左极限还是有极限,使用'+',和'-'表示 |
#极限求解sp.limit()与sp.Limit()
import sympy as sp
'''
sp.limit()函数参数详解:
e:极限表达式,使用定义过的变量和sp.函数名来书写
z:极限自变量
z0:极限自变量趋于的值
dir:左极限还是右极限,用'+','-'表示
'''
'''
sp.Limit()类参数详解:
sp.Limit()类的参数与sp.limit()函数完全一致
二者唯一区别就是一个用来计算结果,一个用来返回表达式
'''
#定义x与y这两个符号变量
x=sp.Symbol('x')
y=sp.Symbol('y')
#极限表达式
expression=(sp.cos(sp.sin(x))-(sp.cos(x)))/(x**4)
result1=sp.limit(e=expression,z=x,z0=0)#result1为极限结果1/6
result2=sp.Limit(e=expression,z=x,z0=0)#result2为极限表示
latex_result1=sp.latex(result1)#转为latex
latex_result2=sp.latex(result2)#转为latex
#使用字符串形式的latex表达式与结果的latex格式字符串连接
#使用jupyter notebook内置的Math与display函数将latex表达式渲染后显示
display(Math(latex_result2))
display(Math(r'\lim_{x\to0}\frac{\cos(sinx)-\cos(x)}{x^4}='+latex_result1))
结果:
当然,对于sp.Limit()类表示的对象,若我们需要求解其极限值,那么只需在其表示的对象后边加一个.doits()方法即可,
微分运算
在sympy中,sp.diff()函数可以用来求解函数的微分,sp.Derivative()类则主要用来表示未计算的
微分表达式(当然,我们也可以通过doit()方法进行求解)。
sp.diff()函数与sp.Derivative()类使用方法:
- sp.diff(fx,(x,n))函数表示对函数表达式fx关于x求n阶导数的表达式。
- sp.Derivative(fx,(x,n))类则只是表示该函数的微分表达式表示出来。
- 要想使用sp.Derivative()实现与sp.diff()一样的效果,只需在该对象后多加一个.doit()方法即可。如下方代码中的diff_result2。
#sp.diff(),sp.Derivative()函数微分求解
import sympy as sp
'''
sp.diff()函数使用方法:
sp.diff(fx,(x,n))表示对函数表达式fx关于x求n阶导数,返回值为微分结果
sp.Derivative()类使用方法:
sp.Derivative(fx,(x,n))表示对函数表达式fx关于x求n阶导数,返回值为微分表达式
'''
#定义x与y这两个符号变量
x,y=sp.symbols('x y')
#极限表达式
fx=sp.ln(1+x)
fxy=sp.ln(x+y)
#保留ln(1+x)5阶导数的表达式
diff_result1=sp.Derivative(fx,x,5)
#计算ln(1+x)关于x的5阶导数并使用doit()方法将Derivative的表达式进行求解
diff_result2=sp.Derivative(fx,x,5).doit()
#计算ln(x+y)关于x的5阶偏导数
diff_result3=sp.diff(fxy,(x,5))
latex_result1=sp.latex(diff_result1)#转为latex
latex_result2=sp.latex(diff_result2)#转为latex
latex_result3=sp.latex(diff_result3)#转为latex
#使用字符串形式的latex表达式与结果的latex格式字符串连接
#使用jupyter notebook内置的Math与display函数将latex表达式渲染后显示
display(Math(latex_result1))
display(Math(r'\frac{d^5ln(1+x)}{dx}='+latex_result2))
display(Math(r'\frac{\partial^5 ln(x+y)}{\partial x}='+latex_result2))
结果:
特别地,当我们想要求解上述导数在某一点处的值,那么只需要对上边的每个result使用subs()方法,将变量替换为数值即可。
这里要注意的是,对于sp.Derivative()对象直接使用subs()方法得到的结果是这个:
正如我们前边所说,这就是个表达式....
因此,要想使用sp.Derivative()求解在某一点处的导数值,我们可以先试用doit()运算求解出导数表达式后再使用subs()方法将值带入,即:
对于使用sp.diff()函数的对象而言,我们使用subs()方法后,返回值是n阶导数在该点处的导数值:
当我们带入微分结果的点是不可导点时,比如在x=0处的导数不存在,那么返回值为NaN
泰勒展开(泰勒级数)
当我们想要获得某个函数在某点处的泰勒展开式时,使用sp.series()便可以快速实现这一过程。
sp.series()函数参数详解:
expr | 函数表达式 |
x | 待展开的函数中的自变量 |
x0 | 展开点,通常是0,即麦克劳林级数 |
n | 阶数 |
#sp.series()泰勒级数
import sympy as sp
'''
sp.series()函数参数详解:
expr:函数表达式
x:待展开的函数中的自变量
x0:展开点,通常是0,即麦克劳林级数
n:阶数
'''
x=sp.symbols('x')
function=sp.sin(x)
Talyorseries1=sp.series(expr=function,x=x,x0=0,n=4)
Talyorseries2=sp.series(expr=function,x=x,x0=2,n=4)
display(Talyorseries1)
display(Talyorseries2)
结果:
积分运算
积分运算包括定积分与不定积分。对于这两种运算,我们都可以使用sp.integrate()函数与sp.Integral()类来进行求解。
sp.integrate()函数用法详解:
- sp.integrate(fx,x)计算fx关于x的不定积分
- sp.inegrate(fx,(x,a,b))计算fx在a,b上的定积分
- sp.integrate(fxy,(x,a,b),(y,c,d))计算xy在abcd区域的二重积分
- 三重积分同理,按照顺序将变量和积分上下限按照元祖的形式传入即可
#sp.integrate,sp. Integral求解积分与不定积分
import sympy as sp
'''
sp.integrate()函数详解:
sp.integrate(fx,x)计算fx关于x的不定积分
sp.inegrate(fx,(x,a,b))计算fx在a,b上的定积分
sp.integrate(fxy,(x,a,b),(y,c,d))计算xy在abcd区域的二重积分
三重积分同理,按照顺序将变量和积分上下限按照元祖的形式传入即可
控制参数详解:
meijerg:bool类型 如果设置为True则使用meijjergG函数计算积分
conds:控制分段积分条件的显示方式。
'none': 不显示条件。
'separate': 单独显示条件。
'piecewise': 将条件合并到分段函数中。
risch:bool类型 如果设置为True则使用risch方法计算积分。
heurisch:bool类型 如果设置为True,则使用启发式算法计算积分。
manual:bool类型 如果设置为True,则手动计算积分(避免自动简化)。
sp.Integral()类使用方法:
传图
'''
x=sp.symbols('x')#积分变量x
a=sp.symbols('a')#未知参数a
result1=sp.integrate(sp.exp(a*x),x,conds='piecewise')#计算不定积分结果
result2=sp.Integral(sp.exp(a*x),x)#只是返回表达式
result3=sp.integrate(sp.exp(a*x),(x,1,2), conds='piecewise')#计算定积分结果sp.integrate()
result4=sp.Integral(sp.exp(a*x),(x,1,2)).doit()#计算定积分结果 sp.Integral().doit()
display(result1)
display(result2)
display(result3)
display(result4)
结果:
这里需要注意的是,sympy在求解一些不定积分或定积分时,只能用于求解一下难度较低的积分,
技巧性稍多,难度稍大一点或者无法求解的积分将返回该积分表达式。
比如:
这是一个较为经典的区间再现积分,但是使用sp.integrate()函数却无法计算。
这里,我手动给出计算过程:
解:令原式=,
,三角换元后,
令,
,
,
换元后
定积分结果与被积变量无关,那么便有:
总结
以上便是Sympy入门之微积分运算的一些基本操作,接下来我们还将介绍Sympy在其他类型运算中的一些应用。敬请期待!