I guess you just need to modify the "if any(...)" line. Currently it
raises ValueError, but I guess what you really want to do is skip
those powers with non-integer exponents.

I guess you also should check if the power is nonnegative, as
otherwise things like 1/x won't do the right thing.

Aaron Meurer

On Wed, Oct 9, 2013 at 8:27 AM, Stewart Martin-Haugh
<[email protected]> wrote:
> Hi,
> This function is really useful, but I'm having problems with combinations of
> sqrt and pow: is there any way to keep the sqrts as they are, but expand
> integer pows?
>
> Thanks,
> Stewart
>
>
> On Thursday, 28 June 2012 15:53:57 UTC+1, Spencer Ogden wrote:
>>
>> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
>
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/sympy.
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sympy.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to