I had a similar problem, and in the end I implemented my own solution before I came across this. Mine seems to be doing much better by reducing the number of operations. However, I also have a set of brute force styles for all combinations of variables. Thus, runtime grows overexponentially in the number of variables. OTOH, I managed to run it on equations with 7 variables in a very reasonable (but far from real time) amount of time.
It is possible that there are several ways to trim some of the search branches, but I was not worried about this. Further optimization is welcome.
def collect_best(expr, measure=sympy.count_ops): # This method performs sympy.collect over all permutations of the free variables, and returns the best collection best = expr best_score = measure(expr) perms = itertools.permutations(expr.free_symbols) permlen = np.math.factorial(len(expr.free_symbols)) print(permlen) for i, perm in enumerate(perms): if (permlen > 1000) and not (i%int(permlen/100)): print(i) collected = sympy.collect(expr, perm) if measure(collected) < best_score: best_score = measure(collected) best = collected return best def product(args): arg = next(args) try: return arg*product(args) except: return arg def rcollect_best(expr, measure=sympy.count_ops): # This method performs collect_best recursively on the collected terms best = collect_best(expr, measure) best_score = measure(best) if expr == best: return best if isinstance(best, sympy.Mul): return product(map(rcollect_best, best.args)) if isinstance(best, sympy.Add): return sum(map(rcollect_best, best.args))
To illustrate performance, this document (paywalled, sorry) has 7 formulas that are 5th degree polynomials in 7 variables with a maximum of 29 terms and 158 operations in extended forms. After applying rcollect_best and @smichr iflfactor number of operations in 7 formulas will be as follows:
[6, 15, 100, 68, 39, 13, 2]
and
[32, 37, 113, 73, 40, 15, 2]
respectively. iflfactor has 433% more operations than rcollect_best for one of the formulas. In addition, the number of operations in advanced formulas:
[39, 49, 158, 136, 79, 27, 2]