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.
