Search⌘ K
AI Features

Matrix Operations

Explore fundamental matrix operations such as transpose, inverse, and trace. Understand their mathematical properties and how to compute them using Python's NumPy library to support data science tasks.

Transpose

A transpose of the matrix Am×nA_{m \times n} is another matrix, An×mTA^T_{n \times m} such that i\forall i, the ithi^{th} row of AA becomes the ithi^{th} column of ATA^T.

Example

A=[123562],AT=[152632]A=\begin{bmatrix}1&2&3\\5&6&2\end{bmatrix} , A^T=\begin{bmatrix}1&5\\2&6\\3&2\end{bmatrix}

Note: The transpose of a symmetric matrix is the same matrix.

Transpose in NumPy

We can use .T to take the transpose of matrices in NumPy. The following code illustrates its use.

Python 3.8
import numpy as np
A = np.round(100*np.random.rand(2, 3))
print('A=\n', A)
print('Transpose of A =\n', A.T) # Inverse using .T

Properties of transpose

  • (A+B)T=AT+BT(A+B)^T=A^T+B^T
  • (AB)T=BTAT(AB)^T=B^TA^T
  • AATAA^T is always symmetric.
  • ATAA^TA is always symmetric.
  • ATA^T and AA have the same determinant: det(A)=det(AT)det(A)=det(A^T). We’ll learn about determinants in a later lesson.
  • ATA^T and AA have the same rank. We’ll learn rank in a later lesson.
  • ATA^T and AA have the same set of eigenvalues. We’ll learn about eigenvalues in a later lesson.

The following code verifies some of these properties:

Python 3.8
import numpy as np
A = np.round(10*np.random.rand(2, 3))
# Symmetric property
print("AAT and ATA are always symmetric")
print('A=\n', A, '\nAAT=\n', A.dot(A.T), '\nATA=\n', A.T.dot(A))
A = np.round(10*np.random.rand(3, 3))
# Determinant property
print("A transpose and A have same determinant")
print('Det(A)=', np.linalg.det(A), '\nDet(AT)=', np.linalg.det(A.T))
# Rank property
print("A transpose and A have same rank")
print('Rank(A)=', np.linalg.matrix_rank(A), '\nRank(AT)=', np.linalg.matrix_rank(A.T))
# Eigenvalues property
print("A transpose and A have same set of eigenvalues")
print('Eigenvalues(A)=', np.sort(np.linalg.eig(A)[0]), '\nEigenvalues(AT)=', np.sort(np.linalg.eig(A.T)[0]))

Inverse

The inverse of a square matrix AA is another matrix, A1A^{-1}, such that AA1=A1A=IAA^{-1}=A^{-1}A=I.

Example

If A=[2305]A=\begin{bmatrix}2&3\\0&5\end{bmatrix}, then A1=[1/23/1001/5]A^{-1}=\begin{bmatrix}1/2&-3/10\\0&1/5\end{bmatrix}.

Note: Not all square matrices have inverses. Some are invertible, and others aren’t.

Inverse in NumPy

We can use .inv() to take the inverse of a square matrix. The following code illustrates its use:

Python 3.8
import numpy as np
A = np.round(10*np.random.rand(3, 3))
Ainv = np.linalg.inv(A) # Inverse using numpy.linalg.inv()
print('A=\n', A, '\nInverse(A)=\n', Ainv, '\nA*Inverse(A)=\n', np.round(A.dot(Ainv)))

Note: We’ll learn how to compute the inverse of a matrix in a later lesson.

Properties of inverse

  • A1A^{-1} is always a square matrix.
  • (A1)1=A(A^{-1})^{-1} = A.
  • det(A1)=1/det(A)det(A^{-1}) = 1/det(A).
  • (AT)1=(A1)T(A^T)^{-1} = (A^{-1})^T.
  • (AB)1=B1A1(AB)^{-1}=B^{-1}A^{-1}.
  • A1A^{-1} and AA have the same eigenvectors.
  • The eigenvalues of A1A^{-1} and AA are reciprocals of each other.

The following code verifies some of these properties:

Python 3.8
import numpy as np
from numpy.linalg import inv
A, B = np.round(10*np.random.rand(2, 2)), np.round(10*np.random.rand(2, 2))
# A = (Inverse(Inverse (A))
print("Applying inverse twice produces original matrix")
print('A=\n', A, '\nInverse(Inverse(A))=\n', inv(inv(A)))
# Inverse(AB) = Inverse(B)Inverse(A)
print("Inverse(AB) equals Inverse(B)Inverse(A)")
print('Inverse(AB)=\n', inv(A.dot(B)), '\nInverse(B)Inverse(A)=\n', inv(B).dot(inv(A)))

Trace

The trace of a square matrix AA is a scalar value, tr(A)tr(A), which is the sum of the main diagonal elements of the matrix.

Example

If A=[2319]A=\begin{bmatrix}2&3\\1&9\end{bmatrix}, then tr(A)=2+9=11tr(A)=2+9=11.

Trace in NumPy

We can use .trace() to compute the trace of a matrix in NumPy. The following code illustrates its use:

Python 3.8
import numpy as np
A = np.round(10*np.random.rand(4, 4))
print('A=\n', A, '\ntr(A)=', np.trace(A))

Properties of trace

  • tr(A+B)=tr(A)+tr(B)tr(A+B)=tr(A)+tr(B)
  • tr(αA)=αtr(A)tr(\alpha A)=\alpha tr(A)
  • tr(ABC)=tr(CAB)=tr(BCA)tr(ABC) = tr(CAB) = tr(BCA)
  • tr(AT)=tr(A)tr(A^T)=tr(A)
  • tr(AB)tr(A)tr(B)tr(AB) \ne tr(A)tr(B)
  • tr(ATA)=tr(AAT)=ijaij2tr(A^TA)=tr(AA^T)=\sum_i\sum_j a^2_{ij}

The following code verifies some of these properties:

Python 3.8
import numpy as np
from numpy import trace as tr
A, B = np.round(10*np.random.rand(3, 3)), np.round(10*np.random.rand(3, 3))
# tr(A)=tr(A transpose)
print('tr(A)=', tr(A), ': tr(transpose(A))=', tr(A.T))
# tr(AB)=tr(A)tr(B)
print('tr(AB)=', tr(A.dot(B)), ': tr(A)tr(B)=', tr(A)*tr(B))
# tr(AB)=tr(B)tr(A)
print('tr(AB)=', tr(A.dot(B)), ': tr(BA)=', tr(B.dot(A)))
# tr(A+B)=tr(A)+tr(B)
print('tr(A+B)=', tr(A+B), ': tr(A)+tr(B)=', tr(A)+tr(B))
#tr(A transpose (A)) = sum of elements of A
print('tr(transpose(A)A)=', tr(A.T.dot(A)), ': sum of squares of elements of A=', np.sum(A.flatten()**2))