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.