Ticket #8659: trac_8659-hold_powers.take2.patch

File trac_8659-hold_powers.take2.patch, 5.6 KB (added by burcin, 8 years ago)
  • module_list.py

    # HG changeset patch
    # User Burcin Erocal <burcin@erocal.org>
    # Date 1306794356 -7200
    # Node ID 9d2b3e04709a4f952eba785e2dd7437a335caddb
    # Parent  0f56af244d2403f6649a6763469134a53cd7a18f
    trac 8659: use the new hold parameter when creating power expressions in the symbolic ring.
    
    We used a hack in the sage.symbolic.power_helper module to prevent running
    into infinite loops when evaluating powers like 2^(1/2). In these cases, the
    symbolics library would call the rational __pow__() method again when trying
    to simplify this expression further. Using the hold functionality merged in
    #9878, we can prevent automatic evalution of power expressions. Thus
    sage.symbolic.power_helper module is not needed any more.
    
    diff --git a/module_list.py b/module_list.py
    a b  
    16691669              depends = ginac_depends + numpy_depends,
    16701670              libraries = ["pynac", "gmp"]),
    16711671
    1672     Extension('sage.symbolic.power_helper',
    1673               sources = ['sage/symbolic/power_helper.pyx'],
    1674               depends = ginac_depends,
    1675               language = 'c++'),
    1676    
    16771672    Extension('sage.symbolic.pynac',
    16781673              sources = ['sage/symbolic/pynac.pyx'],
    16791674              language = 'c++',
  • sage/rings/number_field/number_field_element.pyx

    diff --git a/sage/rings/number_field/number_field_element.pyx b/sage/rings/number_field/number_field_element.pyx
    a b  
    14891489            (PY_TYPE_CHECK(exp, Integer) or PY_TYPE_CHECK_EXACT(exp, int) or exp in ZZ)):
    14901490            return generic_power_c(base, exp, None)
    14911491        else:
    1492             from sage.symbolic.power_helper import try_symbolic_power
    1493             return try_symbolic_power(base, exp)
     1492            # Return a symbolic expression.
     1493            # We use the hold=True keyword argument to prevent the
     1494            # symbolics library from trying to simplify this expression
     1495            # again. This would lead to infite loops otherwise.
     1496            from sage.symbolic.ring import SR
     1497            import operator
     1498            try:
     1499                return QQ(base)**exp
     1500            except TypeError:
     1501                pass
     1502            sbase = SR(base)
     1503            if sbase.operator() is operator.pow:
     1504                nbase, pexp = sbase.operands()
     1505                return nbase.power(pexp * exp, hold=True)
     1506            else:
     1507                return sbase.power(exp, hold=True)
    14941508
    14951509    cdef void _reduce_c_(self):
    14961510        """
  • sage/rings/rational.pyx

    diff --git a/sage/rings/rational.pyx b/sage/rings/rational.pyx
    a b  
    22282228            3/5*(-1)^(1/3)
    22292229            sage: (-27/125)^(1/2)
    22302230            3/5*sqrt(-3/5)
     2231
     2232        The result is normalized to have the rational power in the numerator::
     2233
     2234            sage: 2^(-1/2)
     2235            1/2*sqrt(2)
     2236            sage: 8^(-1/5)
     2237            1/8*8^(4/5)
    22312238        """
    22322239        if dummy is not None:
    22332240            raise ValueError, "__pow__ dummy variable not used"
     
    22622269                    return c * I.pyobject() ** (n.numerator() % 4)
    22632270                elif c != 1:
    22642271                    return c * d**n
    2265                 # this is the only sensible answer that avoids rounding and
    2266                 # an infinite recursion.
    2267                 from sage.symbolic.power_helper import try_symbolic_power
    2268                 return try_symbolic_power(self, n)
     2272                # Can't simplify the power, return a symbolic expression.
     2273                # We use the hold=True keyword argument to prevent the
     2274                # symbolics library from trying to simplify this expression
     2275                # again. This would lead to infite loops otherwise.
     2276                from sage.symbolic.ring import SR
     2277                if n < 0:
     2278                    return SR(1/self)*SR(self).power(1+n, hold=True)
     2279                else:
     2280                    return SR(self).power(n, hold=True)
    22692281
    22702282            if PY_TYPE_CHECK(n, Element):
    22712283                return (<Element>n)._parent(self)**n
  • sage/symbolic/expression.pyx

    diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
    a b  
    24962496            2.2999999999999998^(x^3 - x^2 + 1/3)
    24972497            sage: complex(1,3)^(sqrt(2))
    24982498            (1+3j)^sqrt(2)
     2499
     2500        Test if we can take powers of elements of Q(i) #8659::
     2501
     2502            sage: t = I.pyobject().parent()(8)
     2503            sage: t^(1/2)
     2504            2*sqrt(2)
     2505            sage: (t^2)^(1/4)
     2506            2*4^(1/4)
    24992507        """
    25002508        cdef Expression base, nexp
    25012509       
  • deleted file sage/symbolic/power_helper.pxd

    diff --git a/sage/symbolic/power_helper.pxd b/sage/symbolic/power_helper.pxd
    deleted file mode 100644
    + -  
    1 cpdef object try_symbolic_power(object o, object p)
  • deleted file sage/symbolic/power_helper.pyx

    diff --git a/sage/symbolic/power_helper.pyx b/sage/symbolic/power_helper.pyx
    deleted file mode 100644
    + -  
    1 import ring
    2 
    3 cdef bint __pynac_pow = False
    4 
    5 cpdef object try_symbolic_power(object obj, object p):
    6     """
    7     While evaluating powers, pynac calls Sage again to check if a fractional
    8     power is an exact root. This leads to infinite recursions and crashes.
    9     We use this hack to prevent an infinite recursion.
    10 
    11     TESTS::
    12        
    13         sage: 2^(1/2)
    14         sqrt(2)
    15         sage: (2*I)^(1/2)
    16         sqrt(2*I)
    17 
    18     """
    19     global __pynac_pow
    20     if __pynac_pow:
    21         __pynac_pow = False
    22         return None
    23     else:
    24         try:
    25             __pynac_pow = True
    26             return ring.SR(obj)**ring.SR(p)
    27         finally:
    28             __pynac_pow = False