import pandas as pd
import altair as altDifference quotients from scratch with Python
fastai
Difference quotients from scratch with Python
From the Data Science from Scratch book.
Libraries and helper functions
from typing import List
Vector = List[float]
Vectortyping.List[float]
def dot(vector1: Vector, vector2: Vector) -> float:
assert len(vector1) == len(vector2)
return sum(v1 * v2 for v1, v2 in zip(vector1, vector2))
assert dot([1, 2, 3], [4, 5, 6]) == 32def sum_of_squares(v: Vector) -> Vector:
return dot(v, v)
assert sum_of_squares([1, 2, 3]) == 14Difference quotient
from typing import Callable
def difference_quotient(
f: Callable[[float], float],
x: float,
h: float
) -> float :
return (f(x + h) - f(x)) / hA simple estimate
def square(x: float) -> float:
return x * xdef derivative_x2(x: float) -> float:
return 2 * xxs = range(-10, 11)
actuals = [derivative_x2(x) for x in xs]
actuals[-20,
-18,
-16,
-14,
-12,
-10,
-8,
-6,
-4,
-2,
0,
2,
4,
6,
8,
10,
12,
14,
16,
18,
20]
estimates = [difference_quotient(square, x, h=0.001) for x in xs]
estimates[-19.998999999984335,
-17.998999999988996,
-15.999000000007868,
-13.999000000005424,
-11.99900000000298,
-9.999000000004088,
-7.998999999999867,
-5.998999999999199,
-3.9989999999994197,
-1.998999999999973,
0.001,
2.0009999999996975,
4.000999999999699,
6.000999999999479,
8.0010000000037,
10.001000000002591,
12.001000000005035,
14.00100000000748,
16.000999999988608,
18.000999999983947,
20.000999999993496]
df = pd.DataFrame({'actuals': actuals, 'estimates': estimates}).reset_index()
df = df.melt(id_vars='index')
df.sample(10)| index | variable | value | |
|---|---|---|---|
| 5 | 5 | actuals | -10.000 |
| 13 | 13 | actuals | 6.000 |
| 34 | 13 | estimates | 6.001 |
| 2 | 2 | actuals | -16.000 |
| 19 | 19 | actuals | 18.000 |
| 0 | 0 | actuals | -20.000 |
| 7 | 7 | actuals | -6.000 |
| 3 | 3 | actuals | -14.000 |
| 24 | 3 | estimates | -13.999 |
| 11 | 11 | actuals | 2.000 |
alt.Chart(df).mark_circle(opacity=0.75).encode(
alt.X('index:Q'),
alt.Y('value:Q'),
alt.Size('variable:N'),
alt.Color('variable:N')
).properties(title='Actual derivatives and estimated quotients')Calculating an i-th difference quotient
def partial_difference_quotient(
f: Callable[[Vector], float],
v: Vector,
i: int,
h: float
) -> float:
"""Return i-th parital difference quotient of `f` at a`v`"""
w = [
v_j + (h if j == i else 0)
for j, v_j in enumerate(v)
]
return (f(w) - f(v)) / hdef estimate_gradient(
f: Callable[[Vector], float],
v: Vector,
h: float = 0.0001
):
return [
partial_difference_quotient(f, v, i, h)
for i in range(len(v))
]