Sympy - 比较表达式

Sympy - Comparing expressions

有没有办法检查两个表达式在数学上是否相等?我期望 tg(x)cos(x) == sin(x)输出True,但输出False。有没有办法与 sympy 进行此类比较?另一个例子是 (a+b)**2 == a**2 + 2*a*b + b**2 令人惊讶的是它也输出 False.

我发现了一些类似的问题,但 none 涵盖了这个确切的问题。

来自the SymPy documentation

== represents exact structural equality testing. “Exact” here means that two expressions will compare equal with == only if they are exactly equal structurally. Here, (x+1)^2 and x^2+2x+1 are not the same symbolically. One is the power of an addition of two terms, and the other is the addition of three terms.

It turns out that when using SymPy as a library, having == test for exact symbolic equality is far more useful than having it represent symbolic equality, or having it test for mathematical equality. However, as a new user, you will probably care more about the latter two. We have already seen an alternative to representing equalities symbolically, Eq. To test if two things are equal, it is best to recall the basic fact that if a=b, then a−b=0. Thus, the best way to check if a=b is to take a−b and simplify it, and see if it goes to 0. We will learn later that the function to do this is called simplify. This method is not infallible—in fact, it can be theoretically proven that it is impossible to determine if two symbolic expressions are identically equal in general—but for most common expressions, it works quite well.

作为针对您的特定问题的演示,我们可以使用等价表达式的减法,并像这样与 0 进行比较

>>> from sympy import simplify
>>> from sympy.abc import x,y
>>> vers1 = (x+y)**2
>>> vers2 = x**2 + 2*x*y + y**2
>>> simplify(vers1-vers2) == 0
True
>>> simplify(vers1+vers2) == 0
False

或者,您可以使用 .equals 方法来比较表达式:

from sympy import *
x = symbols('x')

expr1 = tan(x) * cos(x)
expr2 = sin(x)

expr1.equals(expr2)

True

简化的解决方案对我来说太慢了(不得不交叉检查多个变量),所以我写了下面的函数,它预先做了一些简单的检查,以减少计算时间,只在最后一步使用简化。

import numpy as np
import sympy as sp

def check_equal(Expr1,Expr2):
    if Expr1==None or Expr2==None:
        return(False)
    if Expr1.free_symbols!=Expr2.free_symbols:
        return(False)
    vars = Expr1.free_symbols
    your_values=np.random.random(len(vars))
    Expr1_num=Expr1
    Expr2_num=Expr2
    for symbol,number in zip(vars, your_values):
        Expr1_num=Expr1_num.subs(symbol, sp.Float(number))
        Expr2_num=Expr2_num.subs(symbol, sp.Float(number))
    Expr1_num=float(Expr2_num)
    Expr2_num=float(Expr2_num)
    if not np.allclose(Expr1_num,Expr2_num):
        return(False)
    if (Expr1.equals(Expr2)):
        return(True)
    else:
        return(False)

从原来的 sympy 自己检查这个。 https://github.com/sympy/sympy/wiki/Faq

它对我有用的例子