【SymPy】(二)使用SymPy需要避开的坑

在这里插入图片描述

【SymPy】(一)SymPy简介

(二)使用SymPy需要避开的坑

首先,我们应该清楚,SymPy和NumPy、Django一样,不过是一个Python库。这意味着SymPy没有向Python语言添加任何内容。Python语言固有的限制也是SymPy固有的。例如:Python中不允许隐式乘法(如3x3 x),因此SymPy中也不允许隐式乘法。要将3和x相乘,必须用*键入3*x

1 Symbols

SymPy可以在Python可用的任何环境中使用。我们只是导入它,就像导入其他库一样:

In [1]: from sympy import *

现在进行一个运算:

In [2]: x + 1
---------------------------------------------------------------------------
NameError                                 
...
NameError: name 'x' is not defined

我们试图使用变量x,但它告诉我们x没有定义。在Python中,变量在定义之前没有任何意义。SymPy也不例外,它的变量不是自动定义的。为了定义变量,我们必须使用符号symbols.。

In [3]: x = symbols('x')

In [4]: x+1
Out[4]: x + 1

symbols接受由空格或逗号分隔的变量名字符串,并从中创建符号。然后我们可以将它们赋给变量名。

让我们定义最常见的变量名xyz,以便在本文的其余部分中使用

In [5]: x, y, z = symbols('x y z')

注意:符号的名称和它所分配的变量的名称不必相同

In [6]: a, b = symbols('b a')

In [7]: a
Out[7]: b

In [8]: b
Out[8]: a

符号的名称可以超过一个字符:

In [9]: crazy = symbols('unrelated')

In [10]: crazy + 1
Out[10]: unrelated + 1

通常,最好将符号分配给同名的Python变量,不过也有例外:符号名称可以包含Python变量名称中不允许的字符(比如:1x),或者可能只是希望通过将长名称的符号分配给单字母Python变量来避免键入长名称。

最后,为了确保读者理解SymPy符号和Python变量之间的区别。我们来看以下例子:

In [12]: x = symbols('x')

In [13]: expr = x + 1

In [14]: x=2

In [15]: print(expr)
x + 1

x改为2对expr没有影响。这是因为x=2改变的是Python变量x,而对SymPy符号x没有影响,它是我们在创建expr时使用的符号。

当我们创建expr时,Python变量x是一个符号。创建之后,我们将Python变量x更改为2。但是expr保持不变。这种行为并不是SymPy独有的。所有Python程序都是这样工作的:如果一个变量被更改,已经用该变量创建的表达式不会自动更改。例如

In [16]: x = 'abc'

In [17]: expr = x + 'def'

In [18]: expr
Out[18]: 'abcdef'

In [19]: x = 'ABC'

In [20]: expr
Out[20]: 'abcdef'

Tip:要更改表达式中符号的值,使用subs

In [21]: x = symbols('x')

In [22]: expr = x + 1

In [23]: expr.subs(x, 2)
Out[23]: 3

2 等号

SymPy没有扩展Python语法,这导致=在SymPy中也不表示相等,而是Python变量赋值。这是硬编码(hard-coded)到Python语言中的,SymPy没有试图改变这一点。

您可能认为,Python中用于等式测试的== ,被SymPy用作等式。这也不完全正确。

当我们使用==时:

In [4]: x + 1 == 4
Out[4]: False

我们没有得到符号表达式x+1==4,而是得到了False。在SymPy中,==表示精确的结构相等性测试。这意味着a==b相当于我们在问 a是否等于b。我们总是得到一个布尔值作为==的结果。

要创建符号等式,可以通过创建Eq对象:

In [5]: Eq(x + 1, 4)
Out[5]: Eq(x + 1, 4)

关于==还一点需要注意:假设我们想知道 ( x + 1 ) 2 = x 2 + 2 x + 1 (x+1)^{2}=x^{2}+2 x+1 (x+1)2=x2+2x+1是否成立。我们可能会这样做:

In [6]: (x + 1)**2 == x**2 + 2*x + 1
Out[6]: False

回想一下上面的==表示精确的结构相等性测试。这里的“精确”意味着只有当两个表达式在结构上完全相等时,它们用==比较才会得到True

这里, ( x + 1 ) 2 (x+1)^2 (x+1)2 x 2 + 2 x + 1 x^2+2x+1 x2+2x+1在结构上是不同的。一种是两项相加的幂,另一种是三项相加的幂。

我们有我们已经看到了一个替代符号表示相等的方法,Eq。我们知道,如果a=b,那么a−b=0。因此,检查a=b的最佳方法是取a−b并将其简化,然后看看它是否为0。实现简化的函数称为simplify

In [7]: a = (x + 1)**2

In [8]: b = x**2 + 2*x + 1

In [9]: simplify(a - b)
Out[9]: 0

In [10]: c = x**2 - 2*x + 1

In [11]: simplify(a - c)
Out[11]: 4*x

这种方法并不是绝对正确的,但对于大多数常见的表达式,它工作得相当好。

还有一种称为equals的方法,通过在随机点上对两个表达式进行数值求值来检验它们是否相等。

In [12]: a = cos(x)**2 - sin(x)**2

In [13]: b = cos(2*x)

In [14]: a.equals(b)
Out[14]: True

3 ^ 和 /

您可能已经注意到,我们一直使用**而不是标准的^,这是因为SymPy遵循Python的约定。在Python中,^表示逻辑异或。
SymPy也一样:

In [15]: True ^ False
Out[15]: True

In [16]: True ^ True
Out[16]: False

In [17]: Xor(x, y)
Out[17]: Xor(x, y)

最后,就SymPy的工作原理进行一个小的技术讨论。

In [18]: type(Integer(1) + 1)
Out[18]: sympy.core.numbers.Integer

In [19]: type(1 + 1)
Out[19]: int

每当你组合一个SymPy对象和一个SymPy对象,或者一个SymPy对象和一个Python对象,你就得到了一个SymPy对象,但是每当你组合两个Python对象,SymPy永远不会起作用,所以你就得到了一个Python对象。

在SymPy中,两个整数的除法给出一个分数:

In [21]: Integer(1)/Integer(3)
Out[21]: 1/3

In [22]: type(Integer(1)/Integer(3))
Out[22]: sympy.core.numbers.Rational

但在Python/中,表示整数除法或浮点除法,这取决于您是在Python 2中还是Python 3中,以及您是否python2中执行from __future__ import division运行:

In [25]: 1/2
Out[25]: 0.5

运行上述示例时,1/2输出的是0.5,而不是1/2

为了避免这种情况,我们可以显式地构造rational对象

In [26]: Rational(1, 2)
Out[26]: 1/2

每当我们编写一个包含int/int的符号表达式时,这个问题也会出现。例如:

In [27]: x + 1/2
Out[27]: x + 0.5

这是因为Python首先将1/2求值为0.5,然后将其添加到x时将其转换为SymPy类型。

同样,我们可以通过显式创建一个Rational:

In [28]:  x + Rational(1, 2)
Out[28]: x + 1/2

感谢阅读。

未完待续:

【SymPy】(三)基本操作
【SymPy】(四)打印机
【SymPy】(五)简化
【SymPy】(六)微积分
【SymPy】(七)方程求解
【SymPy】(八)矩阵
【SymPy】(九)高级表达式操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二进制人工智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值