I have got two strings in Python,
A m * B s / (A m + C m)
and
C m * B s / (C m + A m)
that are both equivalent functions of the unordered set (A, C) and the unordered set (B). m and s indicate units that can be swapped among the same but not with another unit.
So far, I’m doing permutations of A, B, and C and testing them using eval and SymPy’s == operator. This has multiple drawbacks:
- for more complicated expressions, I have to generate a large number of permutations (in my case 8 nested for loops)
- I need to define A, B, C as symbols, which is not optimal when I don’t know which parameters I will have (so I have to generate all of them -> terribly inefficient and messing up my variable namespace)
Is there a pythonian way to test for this kind of equivalence? It should work an arbitrary expressions.
Here is a simplified approach based on my previous answer.
The idea is that if two expressions are equivalent under permutations, the permutation carrying one to the other must map the ith symbol in the first string (ordered by index of first occurrence) to the ith symbol in the second string (again ordered by index of first occurrence). This principle can be used to construct a permutation, apply it to the first string and then check for equality with the second string – if they are equal they are equivalent, otherwise they are not.
Here is one possible implementation:
As you pointed out, this checks for string equivalence under permutations without any regard to mathematical equivalence, but it is half the battle. If you had a canonical form for mathematical expressions, you could use this approach on two expressions in canonical form. Perhaps one of sympy’s Simplify could do the trick.