使用Python进行字符计算。 第一部分 基础知识

图片

在解决过程和对象的数学建模问题时,使用带有符号计算的Python算法通常非常实用。 Python基于SymPy库,成功地解决了方程和系统的求解,积分和微分,计算极限,级数展开和级数求和,简化表达式以及搜索微分方程和系统的解决方案。

使用符号计算时,通过输入具有给定数量变量的任何有效函数,可以使用户有机会在程序执行期间控制程序。

作为“计算机工程与编程”学科的老师,在Python编程模块中,我向学生介绍了这种语言在科学研究中的可能性。 您的注意力是一系列文章,在这些文章中,您可以熟悉Python中的符号计算。 我想立即警告这些文章并没有绝对的独特性,因为它们是根据各种来源的资料收集的,其目的是向学生传授符号计算的基础知识。

进行符号计算的第一步是使用Python软件包管理系统pip导入SymPy模块的功能。 如果可以处理,让我们继续声明变量。

注意事项 为了缩短记录,以下所有示例均未显示以下行: from sympy import *

明确声明字符变量


对于使用SymPy模块的符号计算必须这样声明符号变量和函数。 在数学计算程序(例如Mathematica或Maple)中,变量立即被视为符号。 在Python中,必须将其强制声明为符号,这可以通过多种方式来完成。 最简单的方法是使用symbol()var()函数。 第一个函数将对字符对象的引用作为变量返回。 第二个,没有分配,创建一个字符变量。

代码示例
>>> x,y,a,b = symbols('xya b') #    ,      >>> f=a**3*x + 3*a**2*x**2/2 + a*x**3 + x**4/4 #  f    >>> type(f) <class 'sympy.core.add.Add'> >>> var('u,v') (u, v) >>> f=sin(u)**2+tan(v) #  f    >>> type(f) <class 'sympy.core.add.Add'> 


symbol()var()函数之间的主要区别在于,第一个函数返回对符号对象的引用。 为了将来使用,必须将其分配给任何变量。 第二个,没有分配,创建一个字符变量。
在symbol()和var()函数中,可以使用索引声明符号变量:

代码示例
 >>> x=symbols('x:9'); x #    0  9 (x0, x1, x2, x3, x4, x5, x6, x7, x8) >>> x=symbols('x5:10'); x #    5  9 (x5, x6, x7, x8, x9) >>> x=var('x:9'); x #    0  9 (x0, x1, x2, x3, x4, x5, x6, x7, x8) >>> x=var('x5:10'); x #    5  9 (x5, x6, x7, x8, x9) 


您还可以直接在symbol()和var()函数中分配类型,并对符号变量施加限制。 有时,没有这样的限制,明显的转换将不起作用,例如,比较:

代码示例
 >>> x = symbols('x', integer=True) #   >>> sqrt(x**2) Abs(x) >>> x = symbols('x', positive = True, integer=True) >>> sqrt(x**2) x >>> x = symbols('x') >>> sqrt(x**2) #  x,  x≥0 sqrt(x**2) >>> x = var('x', integer=True) >>> sqrt(x**2) Abs(x) >>> x = var('x', positive = True, integer=True) >>> sqrt(x**2) x >>> x = var('x') >>> sqrt(x**2) #  x,  x≥0 sqrt(x**2) 


要为单个字符创建容器,请使用参数seq = True:

 >>> symbols('x',seq=True) (x,) 

确定字符变量的有效值:

 >>> x, y, z = symbols('x,y,z', real=True) >>> x.is_real and y.is_real and z.is_real True 

函数s()


有时,字符表达式可以解释为Python数字常量,而不是SymPy。 因此,要声明符号变量以及将数值常量转换为符号,请使用函数S(),例如,进行比较:

 >>> expr = x**2 + sin(y) + S(10)/2; expr x**2 + sin(y) + 5 >>> type(10) <class 'int'> >>> type(S(10)) #    <class 'sympy.core.numbers.Integer'> 

Python常量和字符常量之间的区别在于,与标准round()函数相比,可以按给定的精度计算字符常量,如以下示例所示:

 z=1/7; z #   z    0.14285714285714285 z1=S(1)/7; z1 1/7 z2=z1.n(30); z2 #   z2    30   0.142857142857142857142857142857 z3=round(z1,30); z3 0.14285714285714285 

角色名称


如果您需要在当前会话中不断使用符号数学,则可以从sympy.abc模块导入常见的符号名称:

代码示例
 >>> import sympy.abc >>> dir(sympy.abc) ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_clash', '_clash1', '_clash2', 'a', 'alpha', 'b', 'beta', 'c', 'chi', 'd', 'delta', 'division', 'e', 'epsilon', 'eta', 'exec_', 'f', 'g', 'gamma', 'greeks', 'h', 'i', 'iota', 'j', 'k', 'kappa', 'l', 'lamda', 'm', 'mu', 'n', 'nu', 'o', 'omega', 'omicron', 'p', 'phi', 'pi', 'print_function', 'psi', 'q', 'r', 'rho', 's', 'sigma', 'string', 'symbols', 't', 'tau', 'theta', 'u', 'upsilon', 'v', 'w', 'x', 'xi', 'y', 'z', 'zeta'] 


可以使用命令del name1,name2,..从名称空间中删除变量名称:

 >>> type(x) <class 'sympy.core.symbol.Symbol'> >>> del x,y >>> x NameError: name 'x' is not defined 

要恢复标准常量的值以及某些函数的名称,您需要重新加载sympy模块。

 >>> from sympy import * 

方法子(...)


应当记住,在编写符号表达式时,可以自动执行其简化,例如:

 >>> a,b,c,d,x,y,z,u,v,w = symbols('abcdxyzuv w') >>> x - z + 20 -z- 15 + 3*sin(pi/2)+2*z x + 8 

subs(...)方法用于为给定的变量值计算字符表达式,例如:

 >>> a, x = symbols('a x') >>> f= a**3*x + 3*a**2*x**2/2 + a*x**3 + x**4/4 >>> f.subs(a,1) #   f   a    x**4/4 + x**3 + 3*x**2/2 + x 

如果在subs方法中使用了两个参数,则将它们解释为subs(旧的,新的),即 旧的标识符old被新的new替换。 subs()方法的参数可以是必须包含对(旧,新)的序列,也可以是符号表达式,例如:

 >>> a,b,c,d,x,y,z = symbols('abcdxy z') >>> f=a*x**3 +b*y**2 + c*z+d >>> f.subs([(a,1),(b,2),(c,3),(d,4)]) #   a=1, b=2, c=3, d=4 x**3 + 2*y**2 + 3*z + 4 >>> pr= x**3+4*x**2+6*x+10 >>> pr.subs(x,1/x) #     10 + 6/x + 4/x**2 + x**(-3) 

让我们引起您注意以下使用变量(Python的符号和普通变量)的特殊性。 运行以下代码:

 >>> x='Hello' >>> pr=x+'world' >>> pr 'Helloworld' >>> x='AAA' #   x   >>> pr 'Helloworld' 

该规则适用于此:如果变量已更改,则不会自动重新计算先前创建的包含此变量的表达式。 此规则也适用于常规Python变量。

分数运算


SymPy模块可以使用分数执行计算并将其带到一个公分母,例如,比较:

 >>> S(1)/3+S(2)/5 11/15 >>> 1/3+2/5 0.7333333333333334 

函数有理数(分子,分母)整数(...)用于创建无分数的有理分数:

 >>> z=Rational(1, 7)+Rational(2, 5); z 19/35 >>> Integer(1)/Integer(5) 1/5 >>> 1/5 0.2 >>> z=Integer(1)/Integer(5)+Rational(2, 7); z 17/35 

舍入计算


在符号计算中,该规则有效-如果什么也没说,请不要四舍五入。 了解在第一种情况下,Python如何转换表达式,但将平方根留在响应记录中,并且不执行任何舍入;在第二种情况下,由于其中一个数字用小数点指定,结果将是近似值:

 >>> sqrt(20) 2*sqrt(5) >>> sqrt(20.0) #        4.47213595499958 

对于任何字符对象,都有一个evalf(...)eval uate f loat)方法返回其十进制表示形式:

 >>> sqrt(20).evalf() #  sqrt()  sympy 4.47213595499958 >>> E.evalf() 2.71828182845905 

evalf([n,...])方法可以使用一个参数,指定结果的准确性(n =有效位数)

 >>> sqrt(20).evalf(30) 4.47213595499957939281834733746 >>> pi.evalf(20) 3.1415926535897932385 

您还始终需要记住,实数运算不能返回确切的结果,请进行比较:

 >>> from sympy import * >>> one=S('one') >>> one = cos(1)**2 + sin(1)**2 >>> one.evalf() #  1 1.00000000000000 >>> (one-1).evalf() #    0 -0.e-124 

如果知道结果包含计算错误,则可以使用evalf()方法的chop = True选项将其删除 。 在这种情况下,结果的实部或虚部的很小的值将替换为零。 拿前面的例子:

 >>> (one-1).evalf() #    0 -0.e-124 >>> (one - 1).evalf(chop=True) 0 

无限


从sympy import *执行第一行之后,无穷大符号oo (两个字母“ o”)可用,您还可以使用它们执行某些操作:

 >>> oo+1 oo >>> 1000000<oo True >>> 1/oo 0 

设置积分限制时, limit()integrate()函数主要使用无穷大符号,我们将在以下文章之一中进行讨论。

结论


本文中考虑的符号计算与数值方法的不同之处在于,可以进一步研究结果,例如,确定函数的极值,求解具有嵌入式变量的方程式等。

我希望我的文章对所有对Python编程感兴趣的人,学生以及从事科学研究的人员有所帮助。

Source: https://habr.com/ru/post/zh-CN423731/


All Articles