Aaron,

Thanks for your lead on evaluate=False and the example function. Very close 
for iPad typing and no error checking. I switched around the list 
comprehensions a bit and got it working this way:

from sympy import Symbol, Mul, Pow, pprint, Matrix, symbols

a = Symbol('a')
exp = a**2
print(exp)

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(*list([b]*e for b, e in i.as_base_exp()), 
evaluate=False) for i in pows))
    repl = zip(pows, (Mul(*[b]*e,evaluate=False) for b,e in 
(i.as_base_exp() for i in pows)))
    return expr.subs(repl)

print(pow_to_mul(exp))

This outputs:
a**2
a*a

Thanks again, just what I needed,

Spencer

On Wednesday, June 27, 2012 9:41:04 PM UTC-4, Aaron Meurer wrote:
>
> I don't think there's a built-in function to do this, but it shouldn't be 
> too hard to write your own, using .atoms to find the Pow's and .xreplace 
> (or .subs if you are not using the development version) to replace them. 
>  Note that SymPy automatically converts a*a to a**2, so to keep it as a*a, 
> you have to use Mul(a, a, evaluate=False).  
>
> 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).  So I would not do this until the very end, before you send it 
> to SQL.
>
> Something like this should work:
>
> 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 for b, e in i.as_base_exp()), 
> evaluate=False) for i in pows)
>     return expr.subs(repl)
>     # Or, in the development version, a better way is
>     # return expr.xreplace(dict(repl))
>
> Disclaimer: I typed the above function on my iPad without even checking if 
> the syntax was correct.  It should work, though, assuming I remembered all 
> my interfaces correctly and didn't forget something.
>
> Aaron Meurer
>
> On Jun 27, 2012, at 7:09 PM, Spencer Ogden <[email protected]> wrote:
>
> I'm trying to use sympy to expand matrix math into valid SQL code. SQL 
> doesn't support ** of course, so I would like to expand terms like a**2 to 
> a*a. In the general context of a CAS, this is a silly thing to do, so I 
> haven't been able to locate a function that would do this (expand, replace, 
> rewrite).
>
> Is this possible?
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sympy" group.
> To view this discussion on the web visit 
> https://groups.google.com/d/msg/sympy/-/mTnzsoyEj1UJ.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group at 
> http://groups.google.com/group/sympy?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sympy/-/_5FtUVjZycAJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to