This is in, thank you! Vinzent
2010/2/23 Øyvind Jensen <jensen.oyv...@gmail.com>: > Before, 'refine_Pow' would simplify (-1)**exp only if 'exp' as a whole could > 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 > simply discarded. Odd terms are collected to an even quantity and then > discarded, possibly introducing a new term +1 in the exponent. Finally, > a number N is replaced with N % 2. > > We are now able to refine: > > >>> refine_Pow((-1)**(x+y+z), Assume(x, Q.odd) & Assume(z, Q.odd)) > (-1)**y > >>> refine_Pow((-1)**(x+y+2), Assume(x, Q.odd)) > (-1)**(1 + y) > >>> refine((-1)**(x+3)) > (-1)**(x+1) > > These examples are implemented as doctests and regular tests. > --- > sympy/assumptions/refine.py | 50 ++++++++++++++++++++++++++++++- > sympy/assumptions/tests/test_refine.py | 10 ++++++- > 2 files changed, 57 insertions(+), 3 deletions(-) > > diff --git a/sympy/assumptions/refine.py b/sympy/assumptions/refine.py > index a3ffd18..d81d817 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,25 @@ 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+2), Assume(x, Q.odd)) > + (-1)**(1 + y) > + >>> refine_Pow((-1)**(x+3), True) > + (-1)**(1 + x) > + > + > """ > from sympy.core import Pow, Rational > from sympy.functions import sign > @@ -83,6 +95,40 @@ def refine_Pow(expr, assumptions): > 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: > + > + # For powers of (-1) we can remove > + # - even terms > + # - pairs of odd terms > + # - a single odd term + 1 > + # - A numerical constant N can be replaced with mod(N,2) > + > + coeff, terms = expr.exp.as_coeff_factors() > + terms = set(terms) > + even_terms = set([]) > + odd_terms = set([]) > + initial_number_of_terms = len(terms) > + > + for t in terms: > + if ask(t, Q.even, assumptions): > + even_terms.add(t) > + elif ask(t, Q.odd, assumptions): > + odd_terms.add(t) > + > + terms -= even_terms > + if len(odd_terms)%2: > + terms -= odd_terms > + new_coeff = (coeff + S.One) % 2 > + else: > + terms -= odd_terms > + new_coeff = coeff % 2 > + > + if new_coeff != coeff or len(terms) < > initial_number_of_terms: > + terms.add(new_coeff) > + return expr.base**(Add(*terms)) > + > + > def refine_exp(expr, assumptions): > """ > Handler for exponential function. > diff --git a/sympy/assumptions/tests/test_refine.py > b/sympy/assumptions/tests/test_refine.py > index 58b24b8..59a6dc0 100644 > --- a/sympy/assumptions/tests/test_refine.py > +++ b/sympy/assumptions/tests/test_refine.py > @@ -12,7 +12,7 @@ def test_abs(): > assert refine(abs(x**2), Assume(x, Q.real)) == x**2 > > def test_pow(): > - x, y = symbols('x y') > + x, y, z = symbols('x y z') > assert refine((-1)**x, Assume(x, Q.even)) == 1 > assert refine((-1)**x, Assume(x, Q.odd)) == -1 > assert refine((-2)**x, Assume(x, Q.even)) == 2**x > @@ -30,6 +30,14 @@ def test_pow(): > assert refine(sqrt(1/x), Assume(x, Q.real)) != 1/sqrt(x) > assert refine(sqrt(1/x), Assume(x, Q.positive)) == 1/sqrt(x) > > + # powers of (-1) > + assert refine((-1)**(x+y), Assume(x, Q.even)) == (-1)**y > + assert refine((-1)**(x+y+z), Assume(x, Q.odd)&Assume(z, Q.odd))==(-1)**y > + assert refine((-1)**(x+y+1), Assume(x, Q.odd))==(-1)**y > + assert refine((-1)**(x+y+2), Assume(x, Q.odd))==(-1)**(y+1) > + assert refine((-1)**(x+3)) == (-1)**(x+1) > + > + > def test_exp(): > x = symbols('x') > assert refine(exp(pi*I*2*x), Assume(x, Q.integer)) == 1 > -- > 1.6.5 > > -- > 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.