Great suggestions! I'll create a new patch. Øyvind
ma., 22.02.2010 kl. 14.13 -0700, skrev Aaron S. Meurer: > On Feb 22, 2010, at 12:43 PM, Øyvind Jensen wrote: > > > Before, 'refine_Pow' would simplify (-1)**exp only if 'exp' as a whole > > couold > > be determined as even or odd. A doctest like, > > > > >>> refine_Pow((-1)**(x+y), Assume(x, Q.even)) > > (-1)**y > > > > would fail. This patch fixes that by treating powers of S.NegativeOne as > > a special case. Every term in the exponent is checked, and even terms are > > discarded. After the even terms have been discarded, we check the remaining > > terms for pairs that are even. This fixes another pair of doctests: > > > > >>> refine_Pow((-1)**(x+y+z+1), Assume(x, Q.odd)) > > (-1)**(y + z) > > >>> refine_Pow((-1)**(x+y+z), Assume(x, Q.odd) & Assume(z, Q.odd)) > > (-1)**y > > > > These doctests are included in the patch. > > --- > > sympy/assumptions/refine.py | 41 +++++++++++++++++++++++++++++++++++++++-- > > 1 files changed, 39 insertions(+), 2 deletions(-) > > > > diff --git a/sympy/assumptions/refine.py b/sympy/assumptions/refine.py > > index a3ffd18..42d58c7 100644 > > --- a/sympy/assumptions/refine.py > > +++ b/sympy/assumptions/refine.py > > @@ -1,4 +1,4 @@ > > -from sympy.core import S, Symbol, sympify > > +from sympy.core import S, Symbol, sympify, Add > > from sympy.utilities.source import get_class > > from sympy.assumptions import Q, ask > > from sympy.logic.boolalg import fuzzy_not > > @@ -63,13 +63,23 @@ def refine_Pow(expr, assumptions): > > > >>>> from sympy import Symbol, Assume, Q > >>>> from sympy.assumptions.refine import refine_Pow > > - >>> from sympy.abc import x > > + >>> from sympy.abc import x,y,z > >>>> refine_Pow((-1)**x, Assume(x, Q.real)) > >>>> refine_Pow((-1)**x, Assume(x, Q.even)) > > 1 > >>>> refine_Pow((-1)**x, Assume(x, Q.odd)) > > -1 > > > > + For powers of -1, even parts of the exponent can be simplified: > > + > > + >>> refine_Pow((-1)**(x+y), Assume(x, Q.even)) > > + (-1)**y > > + >>> refine_Pow((-1)**(x+y+z), Assume(x, Q.odd) & Assume(z, Q.odd)) > > + (-1)**y > > + >>> refine_Pow((-1)**(x+y+z+1), Assume(x, Q.odd)) > > + (-1)**(y + z) > > + > > + > > """ > > from sympy.core import Pow, Rational > > from sympy.functions import sign > > @@ -82,6 +92,33 @@ def refine_Pow(expr, assumptions): > > if isinstance(expr.exp, Rational): > > if type(expr.base) is Pow: > > return abs(expr.base.base) ** (expr.base.exp * expr.exp) > > + if expr.base is S.NegativeOne: > > + if expr.exp.is_Add: > > + > > + # see if we can remove single terms in the exponent > > + terms = expr.exp.args > > + removable_terms = set([]) > > + for t in terms: > > + if ask(t, Q.even, assumptions): > > + removable_terms.add(t) > > + if len(removable_terms) > 0: > > + terms = list(set(terms)-removable_terms) > > + > Could you add a test for this part? Just a regular test should be fine > (i.e., in the test_refine.py file). > Also, couldn't you optimize this by skipping over terms in the outer loop if > they have already been tagged for removal? > > + # see if we can remove terms pairwise > > + len_args = len(terms) > > + removable_terms.clear() > > + for i in range(0, len_args-1): > > + for j in range(i+1, len_args): > > + if ask(terms[i]+terms[j], Q.even, assumptions): > > + removable_terms.add(terms[i]) > > + removable_terms.add(terms[j]) > > + > > + if len(removable_terms) > 0: > > + terms = list(set(terms)-removable_terms) > > + > > + if len(expr.exp.args) > len(terms): > > + return expr.base**(Add(*terms)) > > + > > > > def refine_exp(expr, assumptions): > > """ > > -- > > 1.6.5 > How about removing pairs of odd terms too? It would make things easier on > the nested for loop if collect them first. > > Aaron Meurer > > -- > You received this message because you are subscribed to the Google Groups > "sympy-patches" group. > To post to this group, send email to sympy-patc...@googlegroups.com. > To unsubscribe from this group, send email to > sympy-patches+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/sympy-patches?hl=en. > -- You received this message because you are subscribed to the Google Groups "sympy-patches" group. To post to this group, send email to sympy-patc...@googlegroups.com. To unsubscribe from this group, send email to sympy-patches+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sympy-patches?hl=en.