# 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 I_constant = a.expression(constant=True) i = I = a.expression(constant=False) class E(Constant): def __init__(self, name="e"): """ The base of the natural logarithm. EXAMPLES:: sage: RR(e) 2.71828182845905 sage: R = RealField(200); R Real Field with 200 bits of precision sage: R(e) 2.7182818284590452353602874713526624977572470936999595749670 sage: em = 1 + e^(1-e); em e^(-e + 1) + 1 sage: R(em) 1.1793740787340171819619895873183164984596816017589156131574 sage: maxima(e).float() 2.718281828459045 sage: t = mathematica(e)               # optional sage: t                                # optional E sage: float(t)                         # optional 2.7182818284590451 sage: loads(dumps(e)) e """ conversions = dict(axiom='%e', maxima='%e', gp='exp(1)', kash='E', pari='exp(1)', mathematica='E', maple='exp(1)', octave='e') Constant.__init__(self, name, conversions=conversions, latex='e', domain='real') def expression(self): """ .. note:: For e, we don't return a wrapper around a Pynac constant. Instead, we return exp(1) so that Pynac can perform appropiate. EXAMPLES:: sage: e + 2 e + 2 sage: e.operator() exp sage: e.operands() [1] """ from sage.symbolic.ring import SR return SR(1).exp() def __float__(self): """ EXAMPLES:: sage: float(e) 2.7182818284590451 sage: e.__float__() 2.7182818284590451 """ return math.e def _mpfr_(self, R): """ EXAMPLES:: sage: e._mpfr_(RealField(100)) 2.7182818284590452353602874714 """ return R(1).exp() def _real_double_(self, R): """ EXAMPLES:: sage: e._real_double_(RDF) 2.71828182846 """ return R(1).exp() def _sympy_(self): """ Converts e to sympy E. EXAMPLES:: sage: import sympy sage: sympy.E == e # indirect doctest True """ import sympy return sympy.E e = E().expression() # The base of the natural logarithm, e, is not a constant in GiNaC/Sage. It is # represented by exp(1). A dummy class to make this work with arithmetic and # coercion is implemented in the module sage.symbolic.constants_c for speed. from sage.symbolic.constants_c import E e = E() class NotANumber(Constant): """
• ## sage/symbolic/constants_c.pyx

`diff --git a/sage/symbolic/constants_c.pyx b/sage/symbolic/constants_c.pyx`
 a #  version 2 or any later version.  The full text of the GPL is available at: #                  http://www.gnu.org/licenses/ ############################################################################### from sage.symbolic.expression cimport new_Expression_from_GEx from sage.symbolic.expression cimport Expression, new_Expression_from_GEx from sage.symbolic.ring import SR include "../libs/ginac/decl.pxi" include "../ext/stdsage.pxi" cdef extern from "pynac/constant.h": pass foo + 2 """ return new_Expression_from_GEx(SR, (self.pointer[0])) # keep exp(1) for fast access # this is initialized in the constructor of the class E below to prevent # circular imports while loading the library cdef object exp_one cdef class E(Expression): def __init__(self): r""" Dummy class to represent base of the natural logarithm. The base of the natural logarithm ``e`` is not a constant in GiNaC/Sage. It is respresented by ``\exp(1)``. This class provides a dummy object that behaves well under addition, multiplication, etc. and on exponentiation calls the function `exp`. EXAMPLES: The constant defined at the top level is just `exp(1)`:: sage: e.operator() exp sage: e.operands() [1] Arithmetic works:: sage: e + 2 e + 2 sage: 2 + e e + 2 sage: 2*e 2*e sage: e*2 2*e sage: x*e x*e sage: var('a,b') (a, b) sage: t = e^(a+b); t e^(a + b) sage: t.operands() [a + b] Numeric evaluation, conversion to other systems, and pickling works as expected. Note that these are properties of the `exp` function, not this class:: sage: RR(e) 2.71828182845905 sage: R = RealField(200); R Real Field with 200 bits of precision sage: R(e) 2.7182818284590452353602874713526624977572470936999595749670 sage: em = 1 + e^(1-e); em e^(-e + 1) + 1 sage: R(em) 1.1793740787340171819619895873183164984596816017589156131574 sage: maxima(e).float() 2.718281828459045 sage: t = mathematica(e)               # optional sage: t                                # optional E sage: float(t)                         # optional 2.7182818284590451 sage: loads(dumps(e)) e sage: float(e) 2.7182818284590451 sage: e.__float__() 2.7182818284590451 sage: e._mpfr_(RealField(100)) 2.7182818284590452353602874714 sage: e._real_double_(RDF) 2.71828182846 sage: import sympy sage: sympy.E == e # indirect doctest True """ global exp_one exp_one = SR.one_element().exp() Expression.__init__(self, SR, exp_one) def __pow__(left, right, dummy): """ Call the `exp` function when taking powers of `e`. EXAMPLES:: sage: var('a,b') (a, b) sage: t = e^a; t e^a sage: t.operator() exp sage: t.operands() [a] As opposed to:: sage: u = SR(1).exp()^a; u e^a sage: u.operator() sage: u.operands() [e, a] """ if PY_TYPE_CHECK(left, E): if PY_TYPE_CHECK(right, E): return exp_one.exp() return SR(right).exp() else: return SR(left)**exp_one