SymPy中的相同表达式不是==

  • 本文关键字:表达式 SymPy python sympy
  • 更新时间 :
  • 英文 :


我在SymPy中有两个结构相同的表达式,它们以不同的方式创建:

import sympy as sp
f = sp.Symbol('f')
x = sp.Symbol('x')
by_hand = sp.Function(f)(x)
from_string = sp.sympify('f(x)')

尽管两者在结构上是相同的表达式,但它们不是==:

by_hand == from_string
# False

事实上,SymPy甚至不知道它们在符号上是相等的:

sp.simplify(by_hand - from_string)
#   (  )−  (  ) 

两者具有相同的sreprs:

(sp.srepr(by_hand), sp.srepr(from_string))
# ("Function('f')(Symbol('x'))", "Function('f')(Symbol('x'))")
sp.srepr(by_hand) == sp.srepr(from_string)
# True

我知道在SymPy中维护身份不需要可靠的字符串往返,但即使使用locals参数作为修复也不能解决这个问题:

by_hand == sp.sympify('f(x)', locals={'f': f}) == by_hand
# False

必须使用locals已经有些痛苦了,因为我正在尝试对一个例程进行单元测试,该例程通过独立构建符号表达式来构建一堆符号表达式。

有几种方法可以解决这个问题。

修复1

传递locals={'f': sp.Function(f)}而不是locals={'f': f}

by_hand = sp.Function(f)(x)
from_string = sp.sympify('f(x)')
# by_hand == sp.sympify('f(x)', locals={'f': f})                     # Change this
by_hand == sp.sympify('f(x)', locals={'f': sp.Function(f)})  # True  # to this

您定义了by_hand = sp.Function(f)(x),因此sp.srepr(by_hand)中的Function('f')sp.Function(f)sp.Function(sp.Symbol('f'))

另一方面,sp.srepr(from_string)中的Function('f')sp.Function('f')
(这导致我们修复2。)

不同之处在于sp.Function(sp.Symbol('f'))继承了sp.Symbol('f')的默认假设{'commutative': True}
(这导致我们修复3.)

修复2

这是一个干净的解决方案,可能是你想要的。

# f = sp.Symbol('f')  # Change this
f = sp.Function('f')  # to this
x = sp.Symbol('x')
# by_hand = sp.Function(f)(x)  # Change this
by_hand = f(x)                 # to this
from_string = sp.sympify('f(x)')
by_hand == from_string  # True

修复3

该破解演示了Fix 1中确定的继承假设{'commutative': True}

by_hand = sp.Function(f)(x)
del by_hand._kwargs['commutative']         # Add this
# del by_hand._assumptions['commutative']  # Add this, optional
from_string = sp.sympify('f(x)')
by_hand == from_string  # True

最新更新