Reputation: 11
I would like to check which mathematical expressions are equal. I want to do this using Python I tried it with 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. Then I substract them all with each other in my two for loops and check if the result equals to zero.
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?
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])
Upvotes: 1
Views: 1128
Reputation: 19029
The a.equals(b)
method will try really hard (including using random values for variables) to show that 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)
. If you do that then simplify(a - b)
will more likely reduce to 0 as will a.equals(b)
.
posify
is a function which can replace symbols with symbols having positive assumptions; see below how x6 and x7 simplify when symbols are positive:
>>> 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, e.g. 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
. 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))
Upvotes: 1
Reputation: 3279
The Eq
function (from sympy.core.relational
) looks like it is what you want. Note that if it is given more complex arguments, you will have to simplify
to get a result (see last code example in link).
Note: Those for loops don't look right. 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.
Upvotes: 0
Reputation: 566
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
Upvotes: 0