简体   繁体   English

使用 Sympy 将符号数学表达式与 Python 进行比较

[英]Comparing symbolic mathematical expressions with Python using Sympy

I would like to check which mathematical expressions are equal.我想检查哪些数学表达式是相等的。 I want to do this using Python I tried it with Sympy.我想用 Python 来做到这一点,我用 Sympy 试过了。

My idea was to use simplify in order to reduce the expressions such that a pair that is equal will be reduced to the same expression.我的想法是使用simple来减少表达式,这样一对相等的将被简化为相同的表达式。 Then I substract them all with each other in my two for loops and check if the result equals to zero.然后我在我的两个 for 循环中将它们全部相减并检查结果是否等于零。

Unfortunately no substraction results in zero which is very improbable to be correct.不幸的是,没有减法结果为零,这是非常不可能正确的。 I think that probably the simplify function does not really do what I need.我认为可能简化功能并没有真正满足我的需求。 Is there a function in sympy to check if two expressions are indeed mathematically equal? sympy 中是否有一个函数来检查两个表达式在数学上是否确实相等?

This is my code so far:到目前为止,这是我的代码:

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])

The a.equals(b) method will try really hard (including using random values for variables) to show that a == b . a.equals(b)方法会非常努力地(包括对变量使用随机值)来证明a == b But be aware that two expressions might only be equal for a given range of values.但请注意,两个表达式可能仅对给定的值范围相等。 So it might be better to indicate that your symbols are, for example, positive or integer as in Symbol('n', integer=True) or Symbol('a', positive=True) .因此,最好指出您的符号是positiveinteger ,例如Symbol('n', integer=True)Symbol('a', positive=True) If you do that then simplify(a - b) will more likely reduce to 0 as will a.equals(b) .如果你这样做,那么a.equals(b) simplify(a - b)a.equals(b)将更可能减少到0。

posify is a function which can replace symbols with symbols having positive assumptions; posify是一个函数,可以用具有正假设的符号替换符号; see below how x6 and x7 simplify when symbols are positive:当符号为正时,请参阅下面的 x6 和 x7 如何简化:

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

You can also make numerical substitutions yourself using x._random(lo,LO,hi,HI) where (lo, hi) are the lower and upper limit for the real part of the number and (LO, HI) are the same for the imaginary part, eg x._random(0,0,1,0) will give a random value that is real between 0 and 1. Create a replacement dictionary and replace the values and check the absolute value of the difference in a and b .您也可以使用x._random(lo,LO,hi,HI)自己进行数值替换x._random(lo,LO,hi,HI)其中(lo, hi)是数字实部的下限和上限, (LO, HI)是相同的虚部,例如x._random(0,0,1,0)将给出一个介于 0 和 1 之间的实数随机值。创建一个替换字典并替换值并检查ab差值的绝对值。 Something like this (using the loop as you presented it above):像这样(使用上面介绍的循环):

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))

Another way to check if functions are equal would be to evaluate them at maybe a few thousand points and check the outputs. 检查功能是否相等的另一种方法是在大约几千点评估它们并检查输出。

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

From the docs : 从文档

The Eq function (from sympy.core.relational ) looks like it is what you want. Eq函数(来自sympy.core.relational )看起来像是您想要的。 Note that if it is given more complex arguments, you will have to simplify to get a result (see last code example in link). 请注意,如果给它更复杂的参数,则必须simplify以获得结果(请参阅链接中的最后一个代码示例)。

Note: Those for loops don't look right. 注意:那些for循环看起来不正确。 The first one will only go through indices 0-5 and the second only through i+1 to 6, so the last item in the list will be skipped completely. 第一个仅通过索引0-5,第二个仅通过i + 1至6,因此列表中的最后一项将被完全跳过。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM