在 SymPy 中测试 Eq(不是 Expr)的相等性

问题描述 投票:0回答:1

YourHomicidalApe 问了一个问题,本质上是这样的:

给定两个表示转换为 SymPy

Eq
实例的方程的字符串,您如何判断它们是否表示相同的方程? (“相同”意味着可以对每个方程进行代数运算以获得等效表达式,也许以某种规范形式。)

例如,以下方程应该比较相同。可以使用什么工具来做到这一点? 理解不能使用

==
,因为结构相等性测试和
equals
方法显然不适用于
Eq
的实例,除非它们非常相同:

>>> from sympy import *
>>> from sympy.abc import x, y
>>> Eq(y, x).equals(Eq(x, y))
True
>>> Eq(2*y, x).equals(Eq(x/2, y))
False

对于测试如下所示的方程的数学等价性,您有什么建议?

>>> from sympy.parsing import *
>>> a = parse_expr('y=x^2+.5', transformations=T[:])
>>> b = parse_expr('2*y=2x^2+1', transformations=T[:])
>>> a==b
False
>>> a.equals(b)
False
>>> e1, e2 = [i.rewrite(Add) for i in (a, b)]
>>> e1.equals(e2)
False

是否有其他人处理此类表达式,也许是在从代数初学者那里获取输入并根据已知答案进行测试的情况下?

python sympy equality
1个回答
1
投票

正如符号计算中经常出现的情况一样,像“这个表达式是否等于那个表达式”这样看似无辜的问题在一般情况下是无法解决的。由于理查森定理,即使确定两个不同的方程具有相同的左侧和相同的右侧也是不可判定的:

https://en.wikipedia.org/wiki/Richardson%27s_theorem

当然,在很多情况下这个问题可判定的,但正如符号计算中通常的情况一样,需要对问题空间进行一些限制。特别是我们需要以下之一或两者:

  • 我们需要定义一些我们希望能够处理的可能方程或表达式。
  • 我们需要定义允许哪种操作将一个方程转换为另一个方程。

在您的两个示例中,两个方程都是多项式方程,涉及两个具有有理数或浮点系数的变量,因此我们可以将其视为允许的方程类。浮点数是一个潜在的障碍,但我认为在您的用例中,使用

nsimplify
将它们转换为最可能的有理数是可以接受的。在这种情况下,我们的方程是涉及多个变量但具有有理系数的多项式方程。

现在允许什么样的操纵?只有多项式方程的某些操作必然会给出另一个多项式方程:

  • 多项式两边相加或相减。
  • 两边同时乘以有理数或多项式。
  • 两边同时取整数次方。

她提出了一个重要的等式:

您认为

(x - 1)**2 = 0
等同于
(x - 1) = 0
吗?

在某些情况下,区分多项式的因子/根的多重性很重要,但在其他情况下则不然。

另一个考虑因素是您是否希望方程以某些假设为模等效,例如,如果

(x - 1)**2 = y**2
被限制为非负,我们可能会说
x - 1 = y
等于
y
。您可以强加许多可能的假设,因此我不会尝试考虑这些假设。

创建方程(通过解析字符串或其他任何东西)并将浮点数转换为有理数:

In [3]: a = Eq(y, x**2 + 0.5)

In [4]: b = Eq(2*y, 2*x**2 + 1)

In [5]: a
Out[5]: 
     2      
y = x  + 0.5

In [6]: b
Out[6]: 
         2    
2⋅y = 2⋅x  + 1

In [7]: a = nsimplify(a) # float to rational

In [8]: a
Out[8]: 
     2   1
y = x  + ─
         2

现在通过减去边转换为表达式:

In [9]: a = a.lhs - a.rhs

In [10]: b = b.lhs - b.rhs

In [11]: a
Out[11]: 
   2       1
- x  + y - ─
           2

In [12]: b
Out[12]: 
     2          
- 2⋅x  + 2⋅y - 1

最后一步假设您不介意两个方程的每一边都有一个

+ 1
会被取消。也许您确实关心这一点,也许您不关心:这取决于具体情况。以下是您可能关心的示例(如果您的问题空间中允许该方程):

In [19]: eq = Eq(x + 1/x, 1/x)

In [20]: eq
Out[20]: 
    1   1
x + ─ = ─
    x   x

In [21]: solve(eq)
Out[21]: []

In [22]: eq.lhs - eq.rhs
Out[22]: x

In [23]: solve(eq.lhs - eq.rhs)
Out[23]: [0]

在这个阶段,似乎为了使方程等效,您只允许一个是另一个的倍数,但是我们允许乘以什么?我假设这里唯一允许的差异是一个显式有理数因子。在这种情况下,我们可以通过将两个多项式设为单项式来使它们成为规范型多项式:

In [16]: monic(a)
Out[16]: 
 2       1
x  - y + ─
         2

In [17]: monic(b)
Out[17]: 
 2       1
x  - y + ─
         2

In [18]: monic(a) == monic(b)
Out[18]: True

可以定义比这更复杂的等价概念,但这对于给出的示例来说已经足够了。您可以通过概括问题的约束来概括问题,但如果没有一些约束,问题就不可能有算法答案。

© www.soinside.com 2019 - 2024. All rights reserved.