I'm just wondering if there is an existing method of expanding algebraic powers such as x**2
out to their multiplicative forms (i.e. x**2 -> x*x
) in python's Sympy module?
Thanks!
There's no direct support for this. SymPy automatically combines common terms in a multiplication to exponentiation. The only way to make this not happen is to use the evaluate=False
mechanism. For example
>>> Mul(x, x, evaluate=False)
x*x
There was a discussion on the SymPy mailing list a while back about this exact question (https://groups.google.com/d/topic/sympy/qaJGesRbX_0/discussion). I posted some code there that will do this. I'll repeat it here:
def pow_to_mul(expr):
"""
Convert integer powers in an expression to Muls, like a**2 => a*a.
"""
pows = list(expr.atoms(Pow))
if any(not e.is_Integer for b, e in (i.as_base_exp() for i in pows)):
raise ValueError("A power contains a non-integer exponent")
repl = zip(pows, (Mul(*[b]*e,evaluate=False) for b,e in (i.as_base_exp() for i in pows)))
return expr.subs(repl)
Here's how it works
>>> a = Symbol('a')
>>> exp = a**2
>>> print(exp)
a**2
>>> print(pow_to_mul(exp))
a*a
I'll put the same caveat here as on the mailing list: "evaluate=False is somewhat of a hack, so be aware that it is fragile. Some functions will reevaluate the expression, converting it back to Pow. Other functions will break because some expected invariant will be broken by the evaluate=False expression (e.g., I doubt factor() would work correctly)."