I'm solving the Maxwell Garnett equation with SymPy:
solveset(Eq((e-m)/(e+2*m) = n*(a-m)/(a+2*m)), m)
Is it possible to simplify the solution by grouping similar terms together like Mathematica does?
The closest recipe I've found is SymPy: How to collect multi-variable terms?, but it is not directly applicable here.
I've progressed as far as: But how do I get to the even more compact form?
It is possible to call collect
and give it a function that should apply to the coefficients after collection and so we can use factor to factorise the coefficients:
In [2]: e, a, m, n = symbols('e, a, m, n')
In [3]: sol = solveset(Eq((e-m)/(e+2*m), n*(a-m)/(a+2*m)), m)
In [4]: s1, s2 = sol.args[0]
In [5]: s1
Out[5]:
_____________________________________________________________________________
╱ 2 2 2 2 2 2 2 2 2
2⋅a⋅n + a - e⋅n - 2⋅e ╲╱ 4⋅a ⋅n + 4⋅a ⋅n + a + 4⋅a⋅e⋅n - 26⋅a⋅e⋅n + 4⋅a⋅e + e ⋅n + 4⋅e ⋅n + 4⋅e
───────────────────── - ────────────────────────────────────────────────────────────────────────────────
4⋅(n - 1) 4⋅(n - 1)
In [6]: s1.collect(e, lambda c: c.factor() if c.is_polynomial() else c)
Out[6]:
_______________________________________________________
╱ 2 2 ⎛ 2 ⎞ 2 2
a⋅(2⋅n + 1) + e⋅(-n - 2) ╲╱ a ⋅(2⋅n + 1) + 2⋅a⋅e⋅⎝2⋅n - 13⋅n + 2⎠ + e ⋅(n + 2)
──────────────────────── - ──────────────────────────────────────────────────────────
4⋅(n - 1) 4⋅(n - 1)
In [7]: s2.collect(e, lambda c: c.factor() if c.is_polynomial() else c)
Out[7]:
_______________________________________________________
╱ 2 2 ⎛ 2 ⎞ 2 2
a⋅(2⋅n + 1) + e⋅(-n - 2) ╲╱ a ⋅(2⋅n + 1) + 2⋅a⋅e⋅⎝2⋅n - 13⋅n + 2⎠ + e ⋅(n + 2)
──────────────────────── + ──────────────────────────────────────────────────────────
4⋅(n - 1) 4⋅(n - 1)
The is_polynomial
check is to stop collect
from applying factor
to the final expression after it is done recursing subexpressions (a final call to factor expands everything again). There might be a better check that could be used for more general situations.