Vector Algebra ‘from scratch’ with type annotations
I looked into Joel Grus’ Data science from Scratch and found his approach really nice as he actively uses type annotations and assertions in his fuctions.
So, below I practice vector operation functions from the book.
from typing import List
Vector = List[float ]
Vector
Vector addition and subtraction
$ + =
\[\begin{bmatrix} v_1 + w_1 \\ \ldots \\ v_n + w_n \end{bmatrix}\]
$
def add(vector1: Vector, vector2: Vector) -> Vector:
assert len (vector1) == len (vector2)
return [v1 + v2 for v1, v2 in zip (vector1, vector2)]
assert add([1 , 2 , 3 ], [4 , 5 , 6 ]) == [5 , 7 , 9 ]
$ - =
\[\begin{bmatrix} w_1 - v_1 \\ \ldots \\ w_n - v_n \end{bmatrix}\]
$
def subtract(vector1: Vector, vector2:Vector) -> Vector:
assert len (vector1) == len (vector2)
return [v1 - v2 for v1, v2 in zip (vector1, vector2)]
assert subtract([1 , 2 , 3 ], [4 , 5 , 6 ]) == [- 3 , - 3 , - 3 ]
Vector sum
$ + + =
\[\begin{bmatrix} v_1 + \ldots + w_1 \\ \ldots \\ v_n + \ldots + w_n \end{bmatrix}\]
$
def vector_sum(vectors: List[Vector]) -> Vector:
assert vectors
vector_length = len (vectors[0 ])
assert all (len (v) == vector_length for v in vectors)
sums = [0 ] * vector_length
for vector in vectors:
sums = add(sums, vector)
return sums
assert vector_sum([[1 , 2 , 3 ], [4 , 5 , 6 ], [7 , 8 , 9 ]]) == [12 , 15 , 18 ]
Scalar multiplication
$ c =
\[\begin{bmatrix} c \cdot v_0 \\ \ldots \\ c \cdot v_n \end{bmatrix}\]
$
def scalar_multiply(c: float , vector: Vector) -> Vector:
return [c * v for v in vector]
assert scalar_multiply(4 , [1 , 2 , 3 ]) == [4 , 8 , 12 ]
Vector mean
$ (, , ) =
\[\begin{bmatrix} \frac {v_1 + \ldots + w_1}{n} \\ \ldots \\ \frac{v_n + \ldots + w_n} {n} \end{bmatrix}\]
$
def vector_mean(vectors: List[Vector]) -> Vector:
n = len (vectors)
return scalar_multiply(1 / n, vector_sum(vectors))
assert vector_mean([[1 , 2 ], [3 , 4 ], [5 , 6 ]]) == [3 , 4 ]
Dot product
$ = _{i=1}^{n} v_1 w_1 + + v_n w_n $
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 ]) == 32
Vector sum of squares
$ = _{i=1}^n v_1^2 + + v_n^2 $
def sum_of_squares(v: Vector) -> Vector:
return dot(v, v)
assert sum_of_squares([1 , 2 , 3 ]) == 14
Magnitude
$ || || = $
import math as m
def magnitude(v: Vector) -> Vector:
return m.sqrt(sum_of_squares(v))
assert magnitude([1 , 2 , 3 ]) == m.sqrt(14 )
Distance of two vectors
$ d = $
def distance(vector1: Vector, vector2: Vector) -> Vector:
return magnitude(subtract(vector1, vector2))