3 import matplotlib
.pyplot
as plt
4 from collections
.abc
import MutableMapping
5 from fractions
import Fraction
6 from mpmath
import quad
7 from mpl_toolkits
.mplot3d
import axes3d
, Axes3D
8 from matplotlib
import cm
10 class Stack(MutableMapping
):
12 Implements a stack holding variable bindings for execution of translated Maxima code.
13 Provides access via Python dictionary like bindings.
15 def __init__(self
, data
={}, sub
={}):
17 data parameter is a dictionary holding values for the current stack frame.
18 sub is either an instance of Stack or dictionary, holding values at stack frames below the current one.
23 def __getitem__(self
, key
):
24 if key
in self
.mapping
:
25 return self
.mapping
[key
]
29 def __delitem__(self
, key
):
30 if key
in self
.mapping
:
35 def __setitem__(self
, key
, value
):
36 if key
in self
.mapping
:
37 self
.mapping
[key
] = value
43 return iter({**self
.sub
, **self
.mapping
})
46 return len(self
.mapping
) + len(self
.sub
)
49 return f
"{self.mapping}, sub:{self.sub}"
52 self
.mapping
={**self
.mapping
, **data
}
54 # v contains the standard variable mapping from Maxima and is the base for all Stack instances for translated code
62 def plot2d(mapping
, *constraints
, v
= v
):
64 provides functionality for plotting functions in 2D plane.
66 1) A single function/lambda taking one input in the domain defined by constraints.
67 2) List of functions/lambda as defined in 1 above.
70 plot2d(lambda x: x**2, ['x', 0, 1])
71 where 0 and 1 are the lower and upper bounds respectively.
74 if type(mapping
) != list:
77 if len(constraints
) == 1:
78 X
= np
.arange(constraints
[0][1],
82 Y
= np
.array([expr(xi
) for xi
in X
])
86 def plot3d(mapping
, *constraints
, v
= v
):
88 provides functionality for plotting functions in 3D plane.
90 1) A single function/lambda taking two inputs in the domain defined by constraints.
91 2) List of functions/lambda as defined in 1 above.
94 plot2d(lambda x, y: x**2 + y**2, ['x', 0, 1], ['y', 0, 2])
95 where 0 and 1 are the lower and upper bounds respectively for first input and
96 0 and 2 are the lower and upper bounds respectively for the second input.
101 if type(mapping
) != list:
104 vexpr
= np
.vectorize(expr
)
105 if len(constraints
) == 2:
106 X
= np
.arange(constraints
[0][1],
110 Y
= np
.arange(constraints
[1][1],
114 X
, Y
= np
.meshgrid(X
, Y
)
116 surf
= ax
.plot_surface(X
, Y
, Z
, cmap
=cm
.coolwarm
, linewidth
=0, antialiased
=False)
119 # f contains the function mapping used by translated functions from Maxima
123 'factorial': math
.factorial
,
129 'listp': lambda x
: type(x
) == list,
130 'numberp': lambda x
: (type(x
) == int or
132 type(x
) == Fraction
or
133 type(x
) == np
.float64
or
134 type(x
) == np
.float128
or
135 type(x
) == np
.float32
or
136 type(x
) == np
.float16
or
137 type(x
) == np
.float),
139 # As defined in "Concrete Mathematics", Section 3.4
140 'mod': lambda x
,y
: (x
if y
== 0 else x
- y
* math
.floor(x
/ y
)),
141 'emptyp': lambda x
: (True if len(x
) == 0 else False),
142 'first': lambda x
: x
[0],
143 'integerp': lambda x
: type(x
) == int,
144 'append': lambda *x
: [i
for l
in x
for i
in l
],
147 'map': lambda f
, i
: list(map(f
, i
)),
149 'every': lambda func
, l
: all(map(func
, l
)),
153 'signum': lambda x
: 0 if x
==0 else x
/abs(x
)
156 def assign(lhs
, rhs
, v
= v
):