In [1]:
import math
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import os
os.environ["PATH"] += os.pathsep + '/usr/lib/python3.9/site-packages/graphviz/'
In [2]:
def f(x):
return 3*x**2 - 4*x + 5
In [3]:
f(3.0)
Out[3]:
20.0
In [4]:
xs = np.arange(-5,5, .025)
ys = f(xs)
plt.plot(xs, ys)
Out[4]:
[<matplotlib.lines.Line2D at 0x152493e29750>]
In [5]:
h = 0.0000001
x = 3.0
(f(x + h) - f(x))/h
Out[5]:
14.000000305713911
In [6]:
a = 2.0
b = -3.0
c = 10.0
d = a*b + c
print(d)
4.0
In [7]:
h = 0.0001
a = 2.0
b = -3.0
c = 10.0
d1 = a*b + c
a += h
d2 = a*b + c
print('d1', d1)
print('d2', d2)
print('slope', (d2 - d1)/h)
d1 4.0 d2 3.999699999999999 slope -3.000000000010772
In [8]:
h = 0.0001
a = 2.0
b = -3.0
c = 10.0
d1 = a*b + c
b += h
d2 = a*b + c
print('d1', d1)
print('d2', d2)
print('slope', (d2 - d1)/h)
d1 4.0 d2 4.0002 slope 2.0000000000042206
In [9]:
h = 0.0001
a = 2.0
b = -3.0
c = 10.0
d1 = a*b + c
c += h
d2 = a*b + c
print('d1', d1)
print('d2', d2)
print('slope', (d2 - d1)/h)
d1 4.0 d2 4.0001 slope 0.9999999999976694
In [10]:
class Value:
def __init__(self, data):
self.data = data
def __repr__(self):
return f"Value(data={self.data})"
def __add__(self, other):
out = Value(self.data + other.data)
return out
def __mul__(self, other):
out = Value(self.data * other.data)
return out
a = Value(2.0)
b = Value(-3.0)
c = a + b
print('c', c) # c Value(data=-1.0)
c = Value(10.0)
d = a*b + c
#(a.__mul__(b)).__add__(c)
print('d', d)
c Value(data=-1.0) d Value(data=4.0)
In [11]:
class Value:
def __init__(self, data, _children=(), _op = ''):
self.data = data
self._prev = set(_children)
self._op = _op
def __repr__(self):
return f"Value(data={self.data})"
def __add__(self, other):
out = Value(self.data + other.data, (self, other), '+' )
return out
def __mul__(self, other):
out = Value(self.data * other.data, (self, other), '*')
return out
a = Value(2.0)
b = Value(-3.0)
c = a + b
print('c', c) # c Value(data=-1.0)
c = Value(10.0)
d = a*b + c
#(a.__mul__(b)).__add__(c)
print('d', d)
c Value(data=-1.0) d Value(data=4.0)
In [12]:
d._prev # ._prev is showing children {Value(data=-6.0), Value(data=10.0)} ** -6 is the result of a*b i.e. 2 * -3.0
Out[12]:
{Value(data=-6.0), Value(data=10.0)}
In [13]:
d._op # _op shows operation
Out[13]:
'+'
In [14]:
#pip install graphviz
In [15]:
# pacman -Syy
# pacman -Ss graphviz
from graphviz import Digraph
def trace(root):
# builds a set of all notes and edges in a graph
nodes, edges = set(), set()
def build(v):
if v not in nodes:
nodes.add(v)
for child in v._prev:
edges.add((child, v))
build(child)
build(root)
return nodes, edges
def draw_dot(root):
dot = Digraph(format='svg', graph_attr={'rankdir': 'LR'}) # LR = left to Right
nodes, edges = trace(root)
for n in nodes:
uid = str(id(n))
# for any value in the graph, create a rectangular ('record') node for it
dot.node(name = uid, label = "{ data %.4f }" % (n.data, ), shape='record')
if n._op:
# if this value is a result of some operation, create an op node for it
dot.node(name = uid + n._op, label = n._op)
# and connect this node to it
dot.edge(uid + n._op, uid)
for n1, n2 in edges:
#connect n1 to the op node of n2
dot.edge(str(id(n1)), str(id(n2)) + n2._op)
return dot
In [16]:
draw_dot(d)
Out[16]:
In [ ]:
