Ticket #6948: trac_6948-exp_power.patch

File trac_6948-exp_power.patch, 7.5 KB (added by burcin, 13 years ago)
  • sage/symbolic/constants.py

    # HG changeset patch
    # User Burcin Erocal <burcin@erocal.org>
    # Date 1253372662 -7200
    # Node ID b68d64dca26a6dc70b2607fdc2c6852c71d5791f
    # Parent  af08add3a484c624caa4f05bb3614ad8a850ad09
    Prevent automatic simplification of exp(a)^b to exp(a*b) unless b is an integer. #6948
    
    diff --git a/sage/symbolic/constants.py b/sage/symbolic/constants.py
    a b  
    672672I_constant = a.expression(constant=True)
    673673i = I = a.expression(constant=False)
    674674
    675 class E(Constant):
    676     def __init__(self, name="e"):
    677         """
    678         The base of the natural logarithm.
    679 
    680         EXAMPLES::
    681 
    682             sage: RR(e)
    683             2.71828182845905
    684             sage: R = RealField(200); R
    685             Real Field with 200 bits of precision
    686             sage: R(e)
    687             2.7182818284590452353602874713526624977572470936999595749670
    688             sage: em = 1 + e^(1-e); em
    689             e^(-e + 1) + 1
    690             sage: R(em)
    691             1.1793740787340171819619895873183164984596816017589156131574
    692             sage: maxima(e).float()
    693             2.718281828459045
    694             sage: t = mathematica(e)               # optional
    695             sage: t                                # optional
    696             E
    697             sage: float(t)                         # optional
    698             2.7182818284590451
    699 
    700             sage: loads(dumps(e))
    701             e
    702         """
    703         conversions = dict(axiom='%e', maxima='%e', gp='exp(1)',
    704                            kash='E', pari='exp(1)', mathematica='E',
    705                            maple='exp(1)', octave='e')
    706         Constant.__init__(self, name, conversions=conversions,
    707                           latex='e', domain='real')
    708 
    709     def expression(self):
    710         """
    711         .. note::
    712 
    713            For e, we don't return a wrapper around a Pynac constant.
    714            Instead, we return exp(1) so that Pynac can perform appropiate.
    715 
    716         EXAMPLES::
    717 
    718             sage: e + 2
    719             e + 2
    720             sage: e.operator()
    721             exp
    722             sage: e.operands()
    723             [1]
    724         """
    725         from sage.symbolic.ring import SR
    726         return SR(1).exp()
    727    
    728     def __float__(self):
    729         """
    730         EXAMPLES::
    731        
    732             sage: float(e)
    733             2.7182818284590451
    734             sage: e.__float__()
    735             2.7182818284590451
    736         """
    737         return math.e
    738 
    739     def _mpfr_(self, R):
    740         """
    741         EXAMPLES::
    742        
    743             sage: e._mpfr_(RealField(100))
    744             2.7182818284590452353602874714
    745         """
    746         return R(1).exp()
    747 
    748     def _real_double_(self, R):
    749         """
    750         EXAMPLES::
    751        
    752             sage: e._real_double_(RDF)
    753             2.71828182846
    754         """
    755         return R(1).exp()
    756        
    757     def _sympy_(self):
    758         """
    759         Converts e to sympy E.
    760        
    761         EXAMPLES::
    762        
    763             sage: import sympy
    764             sage: sympy.E == e # indirect doctest
    765             True
    766         """
    767         import sympy
    768         return sympy.E
    769 
    770 e = E().expression()
     675# The base of the natural logarithm, e, is not a constant in GiNaC/Sage. It is
     676# represented by exp(1). A dummy class to make this work with arithmetic and
     677# coercion is implemented in the module sage.symbolic.constants_c for speed.
     678from sage.symbolic.constants_c import E
     679e = E()
    771680
    772681class NotANumber(Constant):
    773682    """
  • sage/symbolic/constants_c.pyx

    diff --git a/sage/symbolic/constants_c.pyx b/sage/symbolic/constants_c.pyx
    a b  
    1010#  version 2 or any later version.  The full text of the GPL is available at:
    1111#                  http://www.gnu.org/licenses/
    1212###############################################################################
    13 from sage.symbolic.expression cimport new_Expression_from_GEx
     13from sage.symbolic.expression cimport Expression, new_Expression_from_GEx
    1414from sage.symbolic.ring import SR
    1515
    1616include "../libs/ginac/decl.pxi"
     17include "../ext/stdsage.pxi"
    1718
    1819cdef extern from "pynac/constant.h":
    1920    pass
     
    121122            foo + 2
    122123        """
    123124        return new_Expression_from_GEx(SR, <GEx>(self.pointer[0]))
     125
     126# keep exp(1) for fast access
     127# this is initialized in the constructor of the class E below to prevent
     128# circular imports while loading the library
     129cdef object exp_one
     130
     131cdef class E(Expression):
     132    def __init__(self):
     133        r"""
     134        Dummy class to represent base of the natural logarithm.
     135
     136        The base of the natural logarithm ``e`` is not a constant in GiNaC/Sage.
     137        It is respresented by ``\exp(1)``.
     138
     139        This class provides a dummy object that behaves well under addition,
     140        multiplication, etc. and on exponentiation calls the function `exp`.
     141
     142        EXAMPLES:
     143
     144        The constant defined at the top level is just `exp(1)`::
     145
     146            sage: e.operator()
     147            exp
     148            sage: e.operands()
     149            [1]
     150
     151        Arithmetic works::
     152
     153            sage: e + 2
     154            e + 2
     155            sage: 2 + e
     156            e + 2
     157            sage: 2*e
     158            2*e
     159            sage: e*2
     160            2*e
     161            sage: x*e
     162            x*e
     163            sage: var('a,b')
     164            (a, b)
     165            sage: t = e^(a+b); t
     166            e^(a + b)
     167            sage: t.operands()
     168            [a + b]
     169
     170        Numeric evaluation, conversion to other systems, and pickling works
     171        as expected. Note that these are properties of the `exp` function,
     172        not this class::
     173
     174            sage: RR(e)
     175            2.71828182845905
     176            sage: R = RealField(200); R
     177            Real Field with 200 bits of precision
     178            sage: R(e)
     179            2.7182818284590452353602874713526624977572470936999595749670
     180            sage: em = 1 + e^(1-e); em
     181            e^(-e + 1) + 1
     182            sage: R(em)
     183            1.1793740787340171819619895873183164984596816017589156131574
     184            sage: maxima(e).float()
     185            2.718281828459045
     186            sage: t = mathematica(e)               # optional
     187            sage: t                                # optional
     188            E
     189            sage: float(t)                         # optional
     190            2.7182818284590451
     191
     192            sage: loads(dumps(e))
     193            e
     194
     195            sage: float(e)
     196            2.7182818284590451
     197            sage: e.__float__()
     198            2.7182818284590451
     199            sage: e._mpfr_(RealField(100))
     200            2.7182818284590452353602874714
     201            sage: e._real_double_(RDF)
     202            2.71828182846
     203            sage: import sympy
     204            sage: sympy.E == e # indirect doctest
     205            True
     206        """
     207        global exp_one
     208        exp_one = SR.one_element().exp()
     209        Expression.__init__(self, SR, exp_one)
     210
     211    def __pow__(left, right, dummy):
     212        """
     213        Call the `exp` function when taking powers of `e`.
     214
     215        EXAMPLES::
     216
     217            sage: var('a,b')
     218            (a, b)
     219            sage: t = e^a; t
     220            e^a
     221            sage: t.operator()
     222            exp
     223            sage: t.operands()
     224            [a]
     225
     226        As opposed to::
     227
     228            sage: u = SR(1).exp()^a; u
     229            e^a
     230            sage: u.operator()
     231            <built-in function pow>
     232            sage: u.operands()
     233            [e, a]
     234        """
     235        if PY_TYPE_CHECK(left, E):
     236            if PY_TYPE_CHECK(right, E):
     237                return exp_one.exp()
     238            return SR(right).exp()
     239        else:
     240            return SR(left)**exp_one
     241