【问题标题】:Comparing symbolic mathematical expressions with Python using Sympy使用 Sympy 将符号数学表达式与 Python 进行比较
【发布时间】:2017-10-18 18:09:14
【问题描述】:

我想检查哪些数学表达式是相等的。 我想用 Python 来做这个,我用 Sympy 试过。

我的想法是使用简化来简化表达式,以便将相等的对简化为相同的表达式。 然后我在我的两个 for 循环中将它们全部相减,并检查结果是否等于 0。

不幸的是,没有减法结果为零,这不太可能是正确的。 我认为简化功能可能并没有真正满足我的需要。 sympy 中是否有一个函数来检查两个表达式在数学上是否确实相等?

这是我目前的代码:

from sympy import *

a = symbols ('a')
b = symbols ('b')
n = symbols ('n')
m = symbols ('m')

x1=simplify(log(a,n**(log(b,a))))
x2=simplify(((a**n)/(b**m))**(1/b))
x3=simplify(b**(n*log(a)))
x4=simplify(log(b,n))
x5=simplify(a**((n-m)/b))
x6=simplify(n*(log(a)+log(b)))
x7=simplify(log((a**n)*(b**n)))
x8=simplify(a**(log(b**n)))

L=[x1,x2,x3,x4,x5,x6,x7,x8]



for i in range (0 , 6):

    for k in range (i+1 , 7):

        print(L[i]-L[k])

【问题讨论】:

  • 这些表达式中的任何一个实际上是否相等?我没有看到任何东西。
  • 应该有一些通过执行各种变换在数学上是相等的,例如基地转移等。

标签: python sympy symbolic-math


【解决方案1】:

a.equals(b) 方法将非常努力(包括对变量使用随机值)来证明a == b。但请注意,两个表达式可能仅在给定的值范围内相等。因此,最好指出您的符号是 positiveinteger,如 Symbol('n', integer=True)Symbol('a', positive=True)。如果你这样做,那么simplify(a - b)a.equals(b) 更可能会减少到 0。

posify 是一个可以用具有正假设的符号替换符号的函数;请看下面当符号为正时 x6 和 x7 如何简化:

>>> from sympy import posify
>>> dif = x6 - x7
>>> dif.simplify() == 0
Ealse
>>> posify(dif)[0].simplify()  # [0] gets the the positive-symbol expression

您也可以使用x._random(lo,LO,hi,HI) 自己进行数字替换,其中(lo, hi) 是数字实部的下限和上限,(LO, HI) 与虚部相同,例如x._random(0,0,1,0) 将给出一个介于 0 和 1 之间的随机值。创建一个替换字典并替换这些值并检查 ab 中差异的绝对值。像这样(使用上面介绍的循环):

for i in range (0 , 6):
  for k in range (i+1 , 7):
    v = L[i]-(L[k])
    reps = {i: i._random(0,0,1,0) for i in v.free_symbols}
    v = v.xreplace(reps).n()
    if abs(v) < 1e-9:
      print(L[i],L[k],abs(v))

【讨论】:

    【解决方案2】:

    另一种检查函数是否相等的方法是在几千个点上评估它们并检查输出。

    from sympy import *
    
    def generateOutput(L, x):
        # x -> list of points to evaluate functions at (maybe randomly generated?)
        # L -> input list of functions
        # returns list of outputs of L[i] applied to x
    
    
    
    a = symbols ('a')
    b = symbols ('b')
    n = symbols ('n')
    m = symbols ('m')
    
    x1=simplify(log(a,n**(log(b,a))))
    x2=simplify(((a**n)/(b**m))**(1/b))
    x3=simplify(b**(n*log(a)))
    x4=simplify(log(b,n))
    x5=simplify(a**((n-m)/b))
    x6=simplify(n*(log(a)+log(b)))
    x7=simplify(log((a**n)*(b**n)))
    x8=simplify(a**(log(b**n)))
    
    L=[x1,x2,x3,x4,x5,x6,x7,x8]
    
    outputs = generateOutput(L)
    # Compare outputs
    

    【讨论】:

    • 感谢您的创意!这确实会简化任务。为函数使用大量随机生成的参数应该提供足够的准确性来相互检查它们
    【解决方案3】:

    From the docs:

    Eq 函数(来自sympy.core.relational)看起来就是您想要的。请注意,如果给定更复杂的参数,则必须simplify 才能获得结果(请参阅链接中的最后一个代码示例)。

    注意:那些 for 循环看起来不正确。第一个只会通过索引 0-5,第二个只会通过 i+1 到 6,因此列表中的最后一项将被完全跳过。

    【讨论】:

    • 谢谢,我会努力让它与 Eq 一起工作!关于笔记,我不确定我是否明白这一点。据我了解,我认为第一个 for 循环从 0 迭代到 6(例如 x1 到 x7),第二个从 i+1 迭代到 7。列表中的最后一个元素应该只出现在第二个循环中。这是防止重复计算的效果。我是否在 Python/for 循环中弄错了索引?
    • range 不包含第二个参数(即range(3) == [0,1,2]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    • 2012-01-03
    相关资源
    最近更新 更多