Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

""" 

The constant `e` 

""" 

  

#***************************************************************************** 

# Copyright (C) 2008 William Stein <wstein@gmail.com> 

# Copyright (C) 2008 Burcin Erocal <burcin@erocal.org> 

# Copyright (C) 2009 Mike Hansen <mhansen@gmail.com> 

# 

# This program is free software: you can redistribute it and/or modify 

# it under the terms of the GNU General Public License as published by 

# the Free Software Foundation, either version 2 of the License, or 

# (at your option) any later version. 

# http://www.gnu.org/licenses/ 

#***************************************************************************** 

  

from __future__ import absolute_import, division, print_function 

  

from sage.symbolic.expression cimport Expression 

from sage.symbolic.ring import SR 

  

  

# 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 

  

# Note, the nearest IEEE 754 value of e is NOT the same as the correctly 

# rounded decimal value of e. 

# The numerical value of e = 2.71828182845904523536... 

# Correctly rounded decimal number = 2.7182818284590452 

# Nearest IEEE 754 format number = 2.7182818284590451 

# Value returned on some or all AMD/Intel CPUs = 2.7182818284590451 

# On Sun Blade 1000 with SPARC processors = 2.7182818284590455 

  

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 represented 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 :func:`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 - mathematica 

sage: t # optional - mathematica 

E 

sage: float(t) # optional - mathematica 

2.718281828459045... 

  

sage: loads(dumps(e)) 

e 

  

sage: float(e) 

2.718281828459045... 

sage: e.__float__() 

2.718281828459045... 

sage: e._mpfr_(RealField(100)) 

2.7182818284590452353602874714 

sage: e._real_double_(RDF) # abs tol 5e-16 

2.718281828459045 

sage: import sympy 

sage: sympy.E == e # indirect doctest 

True 

  

TESTS:: 

  

sage: t = e^a; t 

e^a 

sage: t^b 

(e^a)^b 

sage: SR(1).exp() 

e 

  

Testing that it works with matrices (see :trac:`4735`):: 

  

sage: m = matrix(QQ, 2, 2, [1,0,0,1]) 

sage: e^m 

[e 0] 

[0 e] 

""" 

global exp_one 

exp_one = SR.one().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] 

  

This applies to the unit argument as well:: 

  

sage: u = SR(1).exp()^a; u 

e^a 

sage: u.operator() 

exp 

sage: u.operands() 

[a] 

  

It also works with matrices (see :trac:`4735`):: 

  

sage: m = matrix(QQ, 2, 2, [1,0,0,1]) 

sage: e^m 

[e 0] 

[0 e] 

sage: A = matrix(RDF, [[1,2],[3,4]]) 

sage: e^A # rel tol 1e-15 

[51.968956198705044 74.73656456700327] 

[112.10484685050491 164.07380304920997] 

""" 

if isinstance(left, E): 

if isinstance(right, E): 

return exp_one.exp() 

try: 

return right.exp() 

except AttributeError: 

return SR(right).exp() 

else: 

return SR(left)**exp_one