Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expanding algebraic powers in python (sympy)

Tags:

python

sympy

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!

like image 625
user1353285 Avatar asked Jan 10 '13 18:01

user1353285


2 Answers

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)."

like image 167
asmeurer Avatar answered Sep 18 '22 05:09

asmeurer


There seems to be no such thing, it does the reverse only.

sympy always shows the output in the most simple way, so it will always say:

(x**2).expand() -> x**2

simplify(x**2) -> x**2
like image 20
ATOzTOA Avatar answered Sep 17 '22 05:09

ATOzTOA