# 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.

In [1]:
from typing import List
Vector = List[float]
Vector

Out[1]:
typing.List[float]

## Vector addition and subtraction¶

$\vec{v} + \vec{w} = \begin{bmatrix} v_1 + w_1 \\ \ldots \\ v_n + w_n \end{bmatrix}$

In [2]:
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]


$\vec{w} - \vec{v} = \begin{bmatrix} w_1 - v_1 \\ \ldots \\ w_n - v_n \end{bmatrix}$

In [3]:
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¶

$\vec{v} + \ldots + \vec{w} = \begin{bmatrix} v_1 + \ldots + w_1 \\ \ldots \\ v_n + \ldots + w_n \end{bmatrix}$

In [4]:
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 \cdot \vec{v} = \begin{bmatrix} c \cdot v_0 \\ \ldots \\ c \cdot v_n \end{bmatrix}$

In [5]:
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¶

$\text{vector mean}(\vec{w}, \ldots, \vec{v}) = \begin{bmatrix} \frac {v_1 + \ldots + w_1}{n} \\ \ldots \\ \frac{v_n + \ldots + w_n} {n} \end{bmatrix}$

In [6]:
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¶

$\vec{v} \cdot \vec{w} = \sum_{i=1}^{n} v_1 w_1 + \ldots + v_n w_n$

In [7]:
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¶

$\vec{v} \cdot \vec{v} = \sum_{i=1}^n v_1^2 + \ldots + v_n^2$

In [8]:
def sum_of_squares(v: Vector) -> Vector:
return dot(v, v)

assert sum_of_squares([1, 2, 3]) == 14


## Magnitude¶

$|| \vec{v} || = \sqrt {v_1^2 + \ldots + v_n^2}$

In [9]:
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 = \sqrt { (v_1 - w_1)^2 + \ldots + (v_n - w_n)^2 }$

In [10]:
def distance(vector1: Vector, vector2: Vector) -> Vector:
return magnitude(subtract(vector1, vector2))