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.

Reply via email to