1SymPy—符号运算库目录从例子开始欧拉恒等式球体体积数学表达式符号数值运算符和函数符号运算表达式变换和化简方程2目录微分微分方程积分其他功能34SymPy是一个符号数学Python库。它的目标是成为一个全功能的计算机代数系统,同时保持代码的精简而易于理解和可扩展。SymPy完全由Python写成,不需要任何外部库。可用SymPy进行数学表达式的符号推导和演算。可使用isympy运行程序,isympy在IPython的基础上添加了数学表达式的直观显示功能。启动时还会自动运行下面的程序:这段程序首先将Python的除法操作符“/”从整数除法改为普通除法。然后从SymPy库载入所有符号,并且定义了四个通用的数学符号x、y、z、t,三个表示整数的符号k、m、n,以及三个表示数学函数的符号f、g、h。5from__future__importdivisionfromsympyimport*x,y,z,t=symbols('x,y,z,t')k,m,n=symbols('k,m,n',integer=True)f,g,h=symbols('f,g,h',cls=Function)#init_printing()从例子开始欧拉恒等式此公式被称为欧拉恒等式,其中e是自然常数,i是虚数单位,是圆周率。此公式被誉为数学中最奇妙的公式,它将5个基本数学常数用加法、乘法和幂运算联系起来。从SymPy库载入的符号中,E表示自然常数,I表示虚数单位,pi表示圆周率,因此上面的公式可以直接如下计算:6E**(I*pi)+1010ie从例子开始SymPy除了可以直接计算公式的值之外,还可以帮助做数学公式的推导和证明。欧拉恒等式可以将代入下面的欧拉公式得到:在SymPy中可以使用expand()将表达式展开,用它展幵试试看:没有成功,只是换了一种写法而已。当expand()的complex参数为True时,表达式将被分为实数和虚数两个部分:7cossinixexixixeexpand(E**(I*x))exp(I*x)从例子开始这次将表达式展开了,但是得到的结果相当复杂。显然,expand()将x当做复数了。为了指定x为实数,需要重新定义x:终于得到了需要的公式。可以用泰勒多项式对其进行展开:8expand(exp(I*x),complex=True)I*exp(-im(x))*sin(re(x))+exp(-im(x))*cos(re(x))x=Symbol(x,real=True)expand(exp(I*x),complex=True)Isin(x)+cos(x)从例子开始series()对表达式进行泰勒级数展开。可以看到展开之后虚数项和实数项交替出现。根据欧拉公式,虚数项的和应该等于sin(x)的泰勒展开,而实数项的和应该等于cos(x)的泰勒展开。9tmp=series(exp(I*x),x,0,10)printtmp1+I*x-x**2/2-I*x**3/6+x**4/24+I*x**5/120-x**6/720-I*x**7/5040+x**8/40320+I*x**9/362880+O(x**10)tmp从例子开始下面获得tmp的实部:下面对cos(x)进行泰勒展开,可看到其中各项和上面的结果是一致的。10re(tmp)x**8/40320-x**6/720+x**4/24-x**2/2+re(O(x**10))+1series(cos(x),x,0,10)1-x**2/2+x**4/24-x**6/720+x**8/40320+O(x**10)从例子开始11下面获得tmp的虚部:下面对sin(x)进行泰勒展开,其中各项也和上面的结果一致。由于展开式的实部和虚部分别等于cos(x)和sin(x),因此验证了欧拉公式的正确性。im(tmp)x**9/362880-x**7/5040+x**5/120-x**3/6+x+im(O(x**10))series(sin(x),x,0,10)x-x**3/6+x**5/120-x**7/5040+x**9/362880+O(x**10)ixe从例子开始球体体积Scipy介绍了如何使用数值定积分计算球体的体积,SymPy中的integrate()则可以进行符号积分。用integrate()进行不定积分运算:如果指定变量x的取值范围,integrate()就能进行定积分运算:12integrate(x*sin(x),x)-x*cos(x)+sin(x)integrate(x*sin(x),(x,0,2*pi))-2*pi从例子开始为了计算球体体积,首先看看如何计算圆的面积,假设圆的半径为r,则圆上任意一点的Y坐标函数为:因此可以直接对函数y(x)在-r到r区间上进行定积分得到半圆面积。13x,y,r=symbols('x,y,r')f=2*integrate(sqrt(r*r-x**2),(x,-r,r))printf2*Integral(sqrt(r**2-x**2),(x,-r,r))22()yxrx从例子开始首先需要定义运算中所需的符号,这里用symbols()一次创建多个符号。Integrate()没有计算出积分结果,而是直接返冋了输入的算式。这是因为SymPy不知道r是大于0的,重新定义r,就可以得到正确答案了:接下来对此面积公式进行定积分,就可以得到球体的体积,但是随着X轴坐标的变化,对应切面的半径也会发生变化。14r=symbols('r',positive=True)circle_area=2*integrate(sqrt(r**2-x**2),(x,-r,r))printcircle_areapi*r**2从例子开始假设X轴的坐标为x,球体的半径为r,那么x处球的切面半径可以使用前面的公式y(x)计算出。因此需要对圆的面积公式circle_area中的变量r进行替代:然后对circle_area中的变量x在区间-r到r上进行定积分,就可以得到球体的体积公式:15circle_area=circle_area.subs(r,sqrt(r**2-x**2))printcircle_areapi*(r**2-x**2)printintegrate(circle_area,(x,-r,r))4*pi*r**3/3从例子开始16用subs进行算式替换:subs()可以将算式中的符号进行替换,它有3种调用方式:expression.subs(x,y):将算式中的x替换成y.expression.subs({x:y,u:v}):使用字典进行多次替换.expression.subs([(x,y),(u,v)]):使用列表进行多次替換.请注意多次替换是顺序执行的,因此:expression.subs([(x,y),(y,x)])并不能对符号x和y进行交换。数学表达式符号创建一个符号使用symbols(),此函数会返回一个Symbol对象,用于表示符号变量,其有name属性,这是符号名,如:其中左边的x是一个符号对象,而右边括号中用引号包着的x是符号对象的name属性,两个x不要求一样,但是为了易于理解,通常将符号对象和name属性显示成一样,另外name属性是引号包起来的。如要同时配置多个符号对象,symbols()中多个name属性可以以17x0=symbols('x0‘)数学表达式空格或者逗号分隔,然后用引号包住,如下:一次配置三个符号,由于符号对象名和name属性名经常一致,所以可以使用var()函数,如:这语句和上个语句功能一致,在当前环境中创建了4个同名的Symbol对象(为了防止误会,使用symbols其实更好)。18var(x0,y0,x1,y1)(x0,y0,x1,y1)x0,y0,x1,y1=symbols('x0,y0,x1,y1')数学表达式上面的语句创建了名为x0、y0、x1、y1的4个Symbol对象,同时还在当前的环境中创建了4个同名的变量来分别表示这4个Symbol对象。因为符号对象在转换为字符串时直接使用它的name属性,因此在交互式环境中看到变量,x0的值就是x0,但是査看变量x0的类型时就可以发现,它实际上是一个Symbol对象。19x0x0type(x0)sympy.core.symbol.Symbolx0.name'x0'type(x0.name)str数学表达式变量名和符号名当然也可以是不一样的,例如:数学公式中的符号一般都有特定的假设,例如m、n通常是整数,而z经常表示复数。在用var()、symbols()或Symbol()创建Symbol对象时,可以通过关键字参数指定所创建符号的假设条件,这些假设条件会影响到它们所参与的计算。20a,b=symbols(alpha,beta)a,b(alpha,beta)数学表达式例如,下面创建了两个整数符号m和n,以及一个正数符号x:每个符号都有许多is_*属性,用以判断符号的各种假设条件。在IPython中,使用自动完成功能可以快速査看这些假设的名称。注意下划线后为大写字母的属性,用来判断对象的类型;而全小写字母的属性,则用来判断符号的假设条件。21m,n=symbols(m,n,integer=True)x=Symbol(x,positive=True)数学表达式22x.is_#按了tab键自动完成x.is_Symbol#x是一个符号Truex.is_positive#x是一个正数Truex.is_imaginary#因为x可以比较大小,所以它不是虚数Falsex.is_complex#x是一个复数,因为复数包括实数,而实数包括正数True数学表达式23使用assumptions0属性可以快速査看所有的假设条件,其中commutative为True表示此符号满足交换律,其余的假设条件根据英文名很容易知道它们的含义。在SymPy中,所有的对象都从Basic类继承,实际上这些is_*属性和assumptions0属性都是在Basic类中定义的:x.assumptions0Symbol.mro()数学表达式数值为了实现符号运算,在SymPy内部有一整套数值运算系统。因此SymPy的数值和Python的整数、浮点数是完全不同的对象。为了使用方便,SymPy会尽量自动将Python的数值类型转换为SymPy的数值类型。此外,SymPy提供了一个S对象用于进行这种转换。在下面的例子中,当有SymPy的数值参与计算时,结果将是SymPy的数值对象。24数学表达式“5/6”在SymPy中使用Rational对象表示,它由两个整数的商表示,数学上称之为有理数。也可以直接通过Rational创建:251/2+1/3#结果为浮点数0.8333333333333333S(1)/2+1/S(3)#结果为SymPy的数值对象5/6Rational(5,10)#有理数会自动进行约分处理1/2数学表达式26运算符和函数SymPy重新定义了所有的数学运算符和数学函数。例如Add类表示加法,Mul类表示乘法,而Pow类表示指数运算,sin类表示正弦函数。和Symbol对象一样,这些运算符和函数都从Basic类继承,可在IPython中查看它们的继承列表(例如:Add.mro())。可以使用这些类创建复杂的表达式:var(x,y,z,n)Add(x,y,z)x+y+zAdd(Mul(x,y,z),Pow(x,y),sin(z))x*y*z+x**y+sin(z)数学表达式由于在Basic类中重新定义了__add__()等用于创建表达式的方法,因此可以使用和Python表达式相同的方式创建SymPy的