Symbolic Paradigm#
Initial Set-Up#
import sympy as sp
x, y = sp.symbols("x, y")
Predecessor and Successor#
def predecessor(a: sp.Symbol) -> sp.Expr:
return a - 1
assert predecessor(x).subs(x, 1) == 0
assert predecessor(x).subs(x, 10) == 9
def successor(a: sp.Symbol) -> sp.Expr:
return a + 1
assert successor(x).subs(x, 0) == 1
assert successor(x).subs(x, 10) == 11
Addition#
def addition(addend_1: sp.Symbol, addend_2: sp.Symbol) -> sp.Expr:
return addend_1 + addend_2
assert addition(x, y).subs({x: 0, y: 0}) == 0
assert addition(x, y).subs({x: 1, y: 0}) == 1
assert addition(x, y).subs({x: 0, y: 1}) == 1
assert addition(x, y).subs({x: 10, y: 10}) == 20
Multiplication#
def multiplication(multiplicand: sp.Symbol, multiplier: sp.Symbol) -> sp.Expr:
return multiplicand * multiplier
assert multiplication(x, y).subs({x: 0, y: 0}) == 0
assert multiplication(x, y).subs({x: 2, y: 0}) == 0
assert multiplication(x, y).subs({x: 0, y: 2}) == 0
assert multiplication(x, y).subs({x: 10, y: 10}) == 100
Exponentiation#
def exponentiation(base: sp.Symbol, exponent: sp.Symbol) -> sp.Expr:
return base**exponent
assert exponentiation(x, y).subs({x: 1, y: 0}) == 1
assert exponentiation(x, y).subs({x: 0, y: 1}) == 0
assert exponentiation(x, y).subs({x: 3, y: 3}) == 27
What is the particularity of the Symbolic Paradigm?#
z, w, b = sp.symbols("z, w, b")
%%timeit
exponentiation(2, 10) / exponentiation(2, 9)
751 ns ± 4.97 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
%%timeit
(exponentiation(z, w) / exponentiation(z, b)).simplify().subs({z: 2, w: 10, b: 9})
7.13 ms ± 455 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
exponentiation(2, 10000000) / exponentiation(2, 9999999)
78.5 ms ± 570 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%%timeit
(exponentiation(z, w) / exponentiation(z, b)).simplify().subs({z: 2, w: 10000000, b: 9999999})
6.8 ms ± 60.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
exponentiation(2, 1000000000) / exponentiation(2, 999999999)
---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
Cell In[12], line 1
----> 1 get_ipython().run_cell_magic('timeit', '', 'exponentiation(2, 1000000000) / exponentiation(2, 999999999)\n')
File ~/.local/share/virtualenvs/understanding-programming-paradigms-RqbJTeHH/lib/python3.10/site-packages/IPython/core/interactiveshell.py:2430, in InteractiveShell.run_cell_magic(self, magic_name, line, cell)
2428 with self.builtin_trap:
2429 args = (magic_arg_s, cell)
-> 2430 result = fn(*args, **kwargs)
2432 # The code below prevents the output from being displayed
2433 # when using magics with decodator @output_can_be_silenced
2434 # when the last Python token in the expression is a ';'.
2435 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
File ~/.local/share/virtualenvs/understanding-programming-paradigms-RqbJTeHH/lib/python3.10/site-packages/IPython/core/magics/execution.py:1168, in ExecutionMagics.timeit(self, line, cell, local_ns)
1165 if time_number >= 0.2:
1166 break
-> 1168 all_runs = timer.repeat(repeat, number)
1169 best = min(all_runs) / number
1170 worst = max(all_runs) / number
File /usr/lib/python3.10/timeit.py:206, in Timer.repeat(self, repeat, number)
204 r = []
205 for i in range(repeat):
--> 206 t = self.timeit(number)
207 r.append(t)
208 return r
File ~/.local/share/virtualenvs/understanding-programming-paradigms-RqbJTeHH/lib/python3.10/site-packages/IPython/core/magics/execution.py:158, in Timer.timeit(self, number)
156 gc.disable()
157 try:
--> 158 timing = self.inner(it, self.timer)
159 finally:
160 if gcold:
File <magic-timeit>:1, in inner(_it, _timer)
Cell In[6], line 2, in exponentiation(base, exponent)
1 def exponentiation(base: sp.Symbol, exponent: sp.Symbol) -> sp.Expr:
----> 2 return base**exponent
KeyboardInterrupt:
%%timeit
(exponentiation(z, w) / exponentiation(z, b)).simplify().subs({z: 2, w: 1000000000, b: 999999999})
13.8 ms ± 1.27 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)