Lecture 8 - rotations and orthogonal matrices

This lecture considered rotation matrices, which led naturally to the topic on orthogonal matrices.

Orthogonal matrices

A matrix $\boldsymbol{A}$ is orthogonal if $\boldsymbol{A}^{-1} = \boldsymbol{A}^{T}$. A $n \times n$ matrix is orthogonal if its columns form and orthonormal basis.


In [1]:
# Import NumPy and seed random number generator to make generated matrices deterministic
import numpy as np
np.random.seed(1)

# Create a matrix with random entries
A = np.random.rand(4, 4)

# Use QR factorisation of A to create an orthogonal matrix Q (QR is covered in IB)
Q, R = np.linalg.qr(A, mode='complete')

We can now verify that Q is an orthognal matrix. We first check that $\boldsymbol{Q}^{-1} = \boldsymbol{Q}^{T}$ by computing $\boldsymbol{Q}\boldsymbol{Q}^{-1}$


In [2]:
print(Q.dot(Q.T))


[[  1.00000000e+00   4.33680869e-17   4.64038530e-17   9.48676901e-17]
 [  4.33680869e-17   1.00000000e+00   0.00000000e+00  -1.94289029e-16]
 [  4.64038530e-17   0.00000000e+00   1.00000000e+00   0.00000000e+00]
 [  9.48676901e-17  -1.94289029e-16   0.00000000e+00   1.00000000e+00]]

We can see that $\boldsymbol{Q}\boldsymbol{Q}^{-1} = \boldsymbol{I}$ (within numerical precision). We can check that the colums of $\boldsymbol{Q}$ are orthonormal


In [3]:
import itertools

# Build pairs (0,0), (0,1), . . . (0, n-1), (1, 2), (1, 3), . . . 
pairs = itertools.combinations_with_replacement(range(len(Q)), 2)

# Compute dot product of column vectors q_{i} \cdot q_{j}
for p in pairs:
    col0, col1 = p[0], p[1]
    print ("Dot product of column vectors {}, {}: {}".format(col0, col1, Q[:, col0].dot(Q[:, col1])))


Dot product of column vectors 0, 0: 1.0000000000000002
Dot product of column vectors 0, 1: -5.551115123125783e-17
Dot product of column vectors 0, 2: -1.3877787807814457e-16
Dot product of column vectors 0, 3: -6.938893903907228e-18
Dot product of column vectors 1, 1: 1.0000000000000002
Dot product of column vectors 1, 2: 5.551115123125783e-17
Dot product of column vectors 1, 3: -1.942890293094024e-16
Dot product of column vectors 2, 2: 1.0000000000000002
Dot product of column vectors 2, 3: 1.3877787807814457e-17
Dot product of column vectors 3, 3: 1.0000000000000002

The columns of $\boldsymbol{Q}$ are orthonormal, and $\boldsymbol{Q}^{T}$ is also a rotation matrix and has orthonormal columns. Therefore, the rows of $\boldsymbol{Q}$ are also orthonormal.


In [4]:
# Compute dot product of row vectors q_{i} \cdot q_{j}
pairs = itertools.combinations_with_replacement(range(len(Q)), 2)
for p in pairs:
    row0, row1 = p[0], p[1]
    print ("Dot product of row vectors {}, {}: {}".format(row0, row1, Q[row0, :].dot(Q[row1, :])))


Dot product of row vectors 0, 0: 1.0000000000000002
Dot product of row vectors 0, 1: 4.336808689942018e-17
Dot product of row vectors 0, 2: 4.640385298237959e-17
Dot product of row vectors 0, 3: 9.486769009248164e-17
Dot product of row vectors 1, 1: 1.0000000000000002
Dot product of row vectors 1, 2: 0.0
Dot product of row vectors 1, 3: -1.942890293094024e-16
Dot product of row vectors 2, 2: 1.0
Dot product of row vectors 2, 3: 0.0
Dot product of row vectors 3, 3: 1.0000000000000002

Finally, we check the determinant of $\boldsymbol{Q}$:


In [5]:
print("Determinant of Q: {}".format(np.linalg.det(Q)))


Determinant of Q: -1.0000000000000002