This blog is based on Jong-han Kim's Linear Algebra
Linear dependence
set of -vectors is linearly dependent if
holds for some that are not all zero
Linear independence
set of -vectors is linearly independent if
holds only when
e.g., the unit -vectors are linearly independent
Linear combinations of linearly independent vectors
suppose is linear combination of linearly independent vectors
the coefficients are unique, i.e. if
then for
this means that (in principle) we can deduce the coefficients from
to see why, note that
and so (by linear independence)
Independence-dimension inequality
- a linearly independent set of -vectors can have at most elements
- put another way: any set of or more -vectors is linearly dependent
Basis
a set of linearly independent -vectors is called a basis
any -vector can be expressed as a linear combination of them
for some
and these coefficients are unique
formula above is called expansion of in the basis
e.g., is a basis, expansion of is
Orthonormal vectors
set of -vectors are (mutually) orthogonal if for
they are normalized if for
they are orthonormal if both hold
can be expressed using inner products as
orthonormal sets of vectors are linearly independent
by independent-dimension inequality, must have
when are an orthonormal basis
Orthonormal expansion
if is an orthonormal basis, we have for any -vector
called orthonormal expansion of (in the orthonormal basis)
to verify formula, take inner product of both sides with
Gram-Schmidt (orthonormalization) algorithm
- an alorithm to check if are linearly independent
- we'll see later it has many other uses
if G-S does not stop early (in step 2), are linearly independent
if G-S stops early in iteration , then is a linear combination of (so are linearly dependent)
Code
import numpy as np
def gram_schmidt(vectors):
A = np.array(vectors, dtype=float).T
n, k = A.shape
Q = np.zeros((n, k))
for i in range(k):
a_i = A[:, i]
q_tilde = a_i
for j in range(i):
q_j = Q[:, j]
projection = np.dot(q_j.T, a_i) * q_j
q_tilde = q_tilde - projection
norm_q_tilde = np.linalg.norm(q_tilde)
if norm_q_tilde < 1e-10:
print("linear dependent")
return Q[:, :i]
Q[:, i] = q_tilde / norm_q_tilde
return Q
a1 = [1, 1, 0]
a2 = [2, 0, 1]
a3 = [0, 1, 2]
vectors_independent = [a1, a2, a3]
orthonormal_vectors = gram_schmidt(vectors_independent)
print(orthonormal_vectors.T)
print(np.dot(orthonormal_vectors.T, orthonormal_vectors))
print('='*30)
b1 = [1, 0, 1]
b2 = [0, 1, 1]
b3 = [2, 1, 3]
vectors_dependent = [b1, b2, b3]
orthonormal_vectors_dep = gram_schmidt(vectors_dependent)
print(orthonormal_vectors_dep.T)
[[ 0.70710678 0.70710678 0. ]
[ 0.57735027 -0.57735027 0.57735027]
[-0.40824829 0.40824829 0.81649658]]
[[ 1.00000000e+00 2.50235355e-16 1.47380436e-17]
[ 2.50235355e-16 1.00000000e+00 -3.33168241e-17]
[ 1.47380436e-17 -3.33168241e-17 1.00000000e+00]]
==============================
linear dependent
[[ 0.70710678 0. 0.70710678]
[-0.40824829 0.81649658 0.40824829]]