Linear Algebra - Week 2#

Dive into the fundamentals of linear algebra for machine learning and data science. This week you’ll learn to solve equations using the elimination and substitution methods.

[1]:
import numpy as np

Solving a system of equations#

We can solve this system by elimination or substitution.

{5a+b=174a3b=6

Elimination method#

  1. {a+0.2b=3.4a0.75b=1.5

  2. {a+0.2b=3.4a0.75b=1.5

Eliminate a

  1. {a+0.2b=3.400.95b=1.9

  2. {a+0.2b=3.4b=2.

  3. {a=3.b=2.

Substitution method#

  1. {a+0.2b=3.4a0.75b=1.5

  2. {a=3.40.2ba=1.5+0.75b

Substitute a

  1. {a=3.40.2b3.40.2b1.50.75b=0

  2. {a=3.40.2b1.90.95b=0

  3. {a=3.40.2bb=2.

  4. {a=3.b=2.

Let’s check the solution.

[2]:
a = 3.0
b = 2.0

assert 5.0 * a + b == 17.0
assert 4.0 * a - 3.0 * b == 6.0
assert np.allclose(
    np.linalg.solve(np.array([[5.0, 1.0], [4.0, -3.0]]), np.array([17.0, 6.0])),
    np.array([a, b]),
)

Let’s build an elimination algorithm using this system as an example.

{a+b+2c=123a3bc=22ab+6c=24

[3]:
a = np.array([[1, 1, 2], [3, -3, -1], [2, -1, 6]], dtype="float32")
b = np.array([12, 2, 24], dtype="float32")


def solve_by_elimination(a: np.array, b: np.array) -> np.array:
    c = np.hstack((a, b.reshape(-1, 1)))
    for i in range(c.shape[0] - 1):
        # normalize row i
        c[i:, :] /= c[i:, i].reshape(-1, 1)
        # remove row i from row i+1, i+2, etc...
        c = np.vstack((c[: i + 1, :], c[i + 1 :,] - c[i, :]))
    for i in range(c.shape[0] - 1, -1, -1):
        # bring solved (if any) to RHS
        c[i, -1] -= np.sum(c[i, (i + 1) : -1])
        c[i, (i + 1) : -1] = 0
        # divide whole row by coefficient of variable
        c[i, :] /= c[i, i]
        # replace solution across the system
        c[:i, i] *= c[i, -1]
    return c[:, -1]


solve_by_elimination(a, b)
[3]:
array([3.757576 , 2.0606058, 3.0909092], dtype=float32)

Let’s check the solution.

[4]:
assert np.allclose(solve_by_elimination(a, b), np.linalg.solve(a, b))

Let’s try it with another one.

[5]:
a = np.array(
    [[2, -1, 1, 1], [1, 2, -1, -1], [-1, 2, 2, 2], [1, -1, 2, 1]], dtype="float32"
)
b = np.array([6, 3, 14, 8], dtype="float32")
assert np.allclose(solve_by_elimination(a, b), np.linalg.solve(a, b))