You are currently viewing Matrix Operations | Linear Algebra Using Python

Matrix Operations | Linear Algebra Using Python

In linear algebra, understanding the matrix operations is essential for solving a linear system of equations, for obtaining the eigenvalues and eigenvectors, for finding the matrix decompositions and many other applications.

The matrix operations consist of the equality of matrices, the addition, and the subtraction of matrices, the multiplication of matrices and the power of matrices. These operations have numerous interesting properties. We can leverage these properties while performing combinations of these operations to simplify them.

In this article, we will go through these operations and their properties one by one and then we will learn to implement these operations using Python.

Table of Contents

Matrix Operations

The use of various techniques available in linear algebra is impossible without matrix operations. Let’s see what are these matrix operations and their properties in detail.

Equality of Matrices

The conditions for equality of two matrices \(A\) and \(B\) are:

  1. The matrices \(A\) and \(B\) should be of the same order, i.e., the number of rows (\(m\)) of \(A\) should be equal to that of \(B\), and the number of columns (\(n\)) of \(A\) should be equal to that of \(B\).
  2. All the elements of the matrix \(A\) should be equal to the corresponding elements of \(B\).
Equality of Matrices
Equality of Matrices

For example:

\begin{equation}
A= \begin{bmatrix}
a & b\\
c & d\\
e & f
\end{bmatrix} \hspace{2em}
B=
\begin{bmatrix}
a & b\\
c & d\\
e & f
\end{bmatrix}
\end{equation}

Here, the matrices \(A\) and \(B\) are equal.

Addition and Subtraction of Matrices

The order of two matrices should be the same to be able to perform the addition or subtraction operation.

The sum \(A\) + \(B\) is defined, such that each element in the matrix \(A\) adds to the corresponding element in the matrix \(B\).

Addition of Matrices
Addition of Matrices

$$
\begin{aligned}
A= \begin{bmatrix}
a & b\\
c & d\\
e & f
\end{bmatrix} \hspace{2em}
B=
\begin{bmatrix}
k & l\\
m & n\\
p & q
\end{bmatrix}\\[2em]
A+B=
\begin{bmatrix}
a+k & b+l\\
c+m & d+n\\
e+p & f+q
\end{bmatrix}
\hspace{1em}
\end{aligned}
$$

Similarly, we can subtract the matrix \(B\) from the matrix \(A\), by subtracting each element of \(B\) from the corresponding element of \(A\).

Subtraction of Matrices
Subtraction of Matrices

$$
\begin{aligned}
A-B=
\begin{bmatrix}
a-k & b-l\\
c-m & d-n\\
e-p & f-q
\end{bmatrix}
\end{aligned}
$$

Properties of Addition and Subtraction Operation

Following are the properties of addition and subtraction operation:

  • The addition of matrices is commutative.$$\begin{aligned} A+B= B+A \end{aligned} $$
  • The addition and subtraction of matrices is associative.$$ \begin{aligned} (A+B)-C= A+(B-C) \end{aligned}$$
  • The Null Matrix (\(O\)) of the same order is an additive (and subtractive) identity, i.e. the matrix remains the same after addition or subtraction by the matrix \(O\).$$ \begin{aligned} A+O=A \hspace{1em}and\hspace{1em} A-O=A \end{aligned}$$
  • The additive inverse of a matrix is a matrix, when added to the original matrix, results in the Null Matrix.It can be calculated by negating every element of the matrix, i.e., by changing the sign of the element. The additive inverse of the matrix \(A\) is denoted by \(-A\).$$ \begin{aligned}
    A=
    \begin{bmatrix}
    a & b\\
    c & d\\
    e & f
    \end{bmatrix} \hspace{2em}
    -A=
    \begin{bmatrix}
    -a & -b\\
    -c & -d\\
    -e & -f
    \end{bmatrix}\\[2em]
    A+(-A) = O =
    \begin{bmatrix}
    0 & 0\\
    0 & 0\\
    0 & 0
    \end{bmatrix}
    \hspace{2em}
    \end{aligned}$$

Matrix Multiplied by a Scalar

When the matrix multiplied by a scalar value, say \(p\), we obtain the resulting matrix by multiplying each element of the matrix by the scalar \(p\).

Matrix Multiplied by a Scalar
Matrix Multiplied by a Scalar

$$ \begin{aligned}
A&=
\begin{bmatrix}
a & b & c\\
d & e & f
\end{bmatrix} \\[1.5em]
pA &=
\begin{bmatrix}
pa & pb & pc\\
pd & pe & pf
\end{bmatrix}
\end{aligned}$$

Note: When determinant of a matrix is multiplied by a scalar value, then only one line (row or column) is multiplied by that value.

Properties of Scalar Multiplication Operation

The matrix multiplied by a scalar value is a distributive operation.

$$\begin{aligned} p(A+B)= pA+pB \end{aligned}$$

Multiplication of Matrices

We can multiply two matrices (the product \(AB\) is defined) only when they are conformable, i.e., the number of columns in the first matrix should be equal to the number of rows in the second.

$$\begin{aligned}
(m\times n)(n\times k)=(m\times k) \end{aligned}$$

The resulting matrix has the number of rows the same as the first matrix and the number of columns the same as the second matrix.

Matrix Multiplication
Matrix Multiplication

$$\begin{aligned}
A_{2\times3}&=
\begin{bmatrix}
a & b & c \\
d & e & f
\end{bmatrix} \hspace{2em}
B_{3\times2} =
\begin{bmatrix}
l & p \\
m & q \\
n & r
\end{bmatrix} \\[2em]
(AB)_{2\times2} &=
\begin{bmatrix}
al+bm+cn & ap+bq+cr\\
dl+em+fn & dp+eq+fr
\end{bmatrix} \\[0.5em]
\end{aligned}$$

In the matrix multiplication \(AB\), the matrix \(A\) is post-multiplied by the matrix \(B\) and in the multiplication \(BA\), the matrix \(A\) is pre-multiplied by the matrix \(B\).

$$\begin{aligned}
(BA)_{3\times3} =
\begin{bmatrix} la+pd & lb+pe & lc+pf\\
ma+qd & mb+qe & mc+qf\\
na+rd & nb+re & nc+rf \end{bmatrix} \\[0.5em] \end{aligned}$$

The matrix multiplication \(BA\) is defined only when the number of rows in matrix \(A\) (\(m\)) is equal to the number of columns in matrix \(B\) (\(k\)).

Let’s see one example:

$$
\begin{aligned}
A_{2\times3}&=
\begin{bmatrix}
1 & 2 & 3\\
4 & 5 & 6
\end{bmatrix} \hspace{2em}
B_{3\times2} =
\begin{bmatrix}
7 & 10 \\
8 & 11 \\
9 & 12
\end{bmatrix} \\[2em]
(AB)_{2\times2} &=
\begin{bmatrix}
1\times7+2\times8+3\times9 & 1\times10+2\times11+3\times12\\
4\times7+5\times8+6\times9 & 4\times10+5\times11+6\times12\\
\end{bmatrix} \\[0.5em]
&=
\begin{bmatrix}
7+16+27 & 10+22+36\\
28+40+54 & 40+55+72\\
\end{bmatrix} \\[0.5em]
&= \begin{bmatrix}
50 & 68\\
122 & 167\\
\end{bmatrix} \\[2em]
(BA)_{3\times3} &=
\begin{bmatrix}
7\times1+10\times4 & 7\times2+10\times5 &
7\times3+10\times6\\
8\times1+11\times4 & 8\times2+11\times5 &
8\times3+11\times6\\
9\times1+12\times4 & 9\times2+12\times5 &
9\times3+12\times6\\
\end{bmatrix} \\[0.5em]
&=
\begin{bmatrix}
7+40 & 14+50 & 21+60\\
8+44 & 16+55 & 24+66\\
9+48 & 18+60 & 27+72
\end{bmatrix} \\[0.5em]
&=
\begin{bmatrix}
47 & 64 & 81\\
52 & 71 & 90\\
57 & 78 & 99\\
\end{bmatrix}
\end{aligned}$$

In general, if \(A_{m\times n}\) and \(B_{n\times k}\) are two conformable matrices, then the matrix \((AB)_{m\times k}\) is defined as:

$$\begin{aligned}
A_{m\times n} =
\begin{bmatrix}
a_{11} & a_{12} & \dots & a_{1n} \\
a_{21} & a_{22} & \dots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots\\
a_{m1} & a_{m2} & \dots &a_{mn}
\end{bmatrix} \hspace{2em} B_{n\times k} = \begin{bmatrix} b_{11} & b_{12} & \dots & b_{1k} \\ b_{21} & b_{22} & \dots & b_{2k} \\ \vdots & \vdots & \ddots & \vdots\\ b_{n1} & b_{n2} & \dots & b_{nk} \end{bmatrix}\\[3em] (AB)_{m\times k} = \begin{bmatrix} c_{11} & c_{12} & \dots & c_{1k} \\ c_{21} & c_{22} & \dots & c_{2k} \\ \vdots & \vdots & \ddots & \vdots\\ c_{m1} & c_{m2} & \dots & c_{mk} \end{bmatrix}\hspace{2.5cm} \end{aligned}$$

where the term \(c_{ij}\) is called the inner product of the \(i^{th}\) row of \(A\) and the \(j^{th}\) column of \(B\) and is obtained by summing the multiplication of the elements of the \(i^{th}\) row by the corresponding elements of the \(j^{th}\) column.

$$\begin{aligned}
c_{ij} =
a_{i1}b_{1j} + a_{i2}b_{2j} + a_{i3}b_{3j} + \dots + a_{in}b_{nj} \end{aligned}$$

Properties of Matrix Multiplication

Following are the properties of matrix multiplication operation:

  • Multiplication of matrices is NOT commutative.$$\begin{aligned} AB\neq BA \end{aligned}$$provided \(BA\) is defined. Also, \(AB\) can be equal to \(BA\) for some cases of \(A\) and \(B\), but it is very rare.
  • Matrix multiplication is associative.$$\begin{aligned} (AB)C = A(BC) \end{aligned}$$ where A, B and B, C should be conformable for the products AB and BC to be defined, respectively.
  • Matrix multiplication is distributive.$$\begin{aligned}
    A(B+C) &= AB+AC\\[0.5em] (A+B)C &= AC+BC \end{aligned}$$

    where the corresponding matrices should be conformable for the products to be defined.

  • Transpose of the matrix multiplication is defined by taking the transpose of individual matrices and reversing their position.$$\begin{aligned}
    (AB)^T &= B^TA^T
    \end{aligned}$$

    Matrices remain conformable after taking the transpose and reversing the order.

  • Associativity of the product by a scalar quantity of \(c\) with the matrix multiplication is defined as$$\begin{aligned}
    (AB)c &= A(Bc)\\[0.5em]
    c(AB) &= (cA)B
    \end{aligned}$$

    provided, the matrix multiplication \(AB\) is defined, i.e., \(A\) and \(B\) are conformable.

  • There exists a multiplicative identity \(I\), when multiplied with the matrix, results in the original matrix.$$\begin{aligned} I_mA = AI_n = A\\[0.5em] \end{aligned}$$where \(I\) is an Identity Matrix of the corresponding order, which makes both the matrices conformable.

Power of a Matrix

We can define the power of a matrix as the multiplication of two matrices. The square of matrix \(A\) can be defined as the product \(AA\) and the cube of matrix \(A\) is defined as the multiplication of \(A\) and \(A^2\).

Power of a Matrix
Power of a Matrix

$$
\begin{aligned}
A^2 &= AA \\[0.5em]
A^3 &= AA^2
\end{aligned}
$$

In general, the \(n^{th}\) power of matrix \(A\) is defined as:

$$
\begin{aligned}
A^n &= AA^{n-1}\\[0.5em]
&= A(AA^{n-2})
\end{aligned}
$$

Properties of Power Operation

  • If the square of a matrix is an identity matrix, then that matrix is said to be an Involutory Matrix, i.e., \(A^2=I\).
  • If the square of the matrix results in the same matrix, i.e., if \(A^2=A\), then matrix A is called an Idempotent Matrix
  • If the square of the matrix results in the Null Matrix, i.e., if \(A^2=0\), then matrix A is called a Nilpotent Matrix

Matrix Operations Using Python

We will use the NumPy library to perform the matrix operations. This library has all the necessary functions for checking the matrix equality, the matrix multiplication, the power of a matrix, etc. predefined.

To install the Numpy library, we can use

pip install numpy

I suggest you to use Jupyter Notebook to follow the contents of this part of the article. Check my other article on setting up Python for scientific computing to get started.

Let’s import the NumPy library with an alias np using

import numpy as np

Now we are ready to get started with the implementation of matrix operations using Python.

Check for Equality of Matrices Using Python

The NumPy library of Python provides multiple ways to check the equality of two matrices. Let’s go through them one by one.

Few of the available functions check and output the element-wise equality of the matrices. The output is also a matrix of the same order as the given matrices containing boolean values (True or False). If all the element-wise checks are True, then the matrices are equal.

On the other hand, few functions check for the equality of matrices as a whole and output single boolean value (True or False) indicating the equality of matrices.

Element-wise Equality Check

The functions showing the element-wise comparison are:

  • numpy.equal( )The numpy.equal( ) function checks if the elements of the given matrices are exactly equal.
      A = np.array([[1,2,3],[4,5,6]])
      B = np.array([[1,2,3],[4,5,6]])
      C = np.array([[1.0000001,2,3],[4,5.00000001,6]]) 
    
      print('Matrix A:')
      print(A)
      print('Matrix B:')
      print(B)
      print('Matrix C:')
      print(C)
    
      print('Check for the equality of Matrices A and B:')
      print(np.equal(A,B))
    
      print('Check for the equality of Matrices A and C:')
      print(np.equal(A,C))

    Output:

      Matrix A:
      [[1 2 3]
       [4 5 6]]
      Matrix B:
      [[1 2 3]
       [4 5 6]]
      Matrix C:
      [[1.0000001  2.         3.  ]
       [4.         5.00000001 6.  ]]
      Check for the equality of Matrices A and B:
      [[ True  True  True]
       [ True  True  True]]
      Check for the equality of Matrices A and C:
      [[False  True  True]
       [ True False  True]]

    As we can observe that the elements of matrices \(A\) and \(C\) are almost equal, but the numpy.equal( ) function flags them as not-equal.

    In that case, another function from the NumPy library comes in handy if we want to check if the elements of two matrices are within some acceptable tolerance.

  • numpy.isclose( )Unlike the numpy.equal( ) function, the numpy.isclose( ) function allows us to set a tolerance limit within which the elements of the matrices are said to be equal.The formula used for checking the equality of corresponding elements of the two matrices is$$absolute(a – b) <= (atol + rtol * absolute(b))$$The default value of the absolute tolerance parameter is atol=1e-8 and that of the relative tolerance parameter is rtol=1e-5.
      A = np.array([[1,2,3],[4,5,6]])
      B = np.array([[1,2,3],[4,5,6]])
      C = np.array([[1.0000001,2,3],[4,5.00000001,6]]) 
    
      print('Matrix A:')
      print(A)
      print('Matrix B:')
      print(B)
      print('Matrix C:')
      print(C)
    
      print('Check for the equality of Matrices A and B:')
      print(np.isclose(A,B))
    
      print('Check for the equality of Matrices A and C:')
      print(np.isclose(A,C))

    Output:

      Matrix A:
      [[1 2 3]
       [4 5 6]]
      Matrix B:
      [[1 2 3]
       [4 5 6]]
      Matrix C:
      [[1.0000001  2.         3.  ]
       [4.         5.00000001 6.  ]]
      Check for the equality of Matrices A and B:
      [[ True  True  True]
       [ True  True  True]]
      Check for the equality of Matrices A and C:
      [[ True  True  True]
       [ True  True  True]]

    Notice that the \(1^{st}\) and \(5^{th}\) elements of the same matrices were indicated as not equal when we used the numpy.equal( ) function.

    We can specify the value of the tolerance parameters according to our needs because the absolute tolerance parameter value atol=1e-8 might not be appropriate for some cases. For example, when the matrices have the values of the elements much smaller than one.

      P = np.array([[1,2,3],[4,5,1e-5]])
      Q = np.array([[1.0000001,2,3],[4,5.00000001,0.99e-5]]) 
    
      print('Matrix P:')
      print(P)
      print('Matrix Q:')
      print(Q)
    
      print('Check for the equality of Matrices P and Q with lower tolerance:')
      print(np.isclose(P,Q,atol=1e-8))

    Output:

      Matrix P:
      [[1.e+00 2.e+00 3.e+00]
       [4.e+00 5.e+00 1.e-05]]
      Matrix Q:
      [[1.00000010e+00 2.00000000e+00 3.00000000e     +00]
       [4.00000000e+00 5.00000001e+00 9.      90000000e-06]]
      Check for the equality of Matrices P and Q      with lower tolerance:
      [[ True  True  True]
       [ True  True False]]

    Notice the last element of matrices \(P\) and \(Q\).

Equality Check with Matrix as a Whole

Contrary to the previous functions, few functions in the NumPy library offer a way to get a single boolean value as an output for comparison. Therefore, these functions have an added advantage that we can use them in conditional statements.

Following functions return True or False, when two matrices are entered as inputs:

  • numpy.array_equal( )The numpy.array_equal( ) function returns True if the shapes of two matrices are the same and all the corresponding elements of the matrices are equal.This function can be thought of as matrix level equivalent of the previously discussed numpy.equal( ) function, i.e., when all the elements of the matrix returned by numpy.equal( ) are True, the numpy.array_equal( ) function will return single True value for the same set of input matrices.If any of the elements of the matrix returned by numpy.equal( ) are False, the numpy.array_equal( ) function will return False for the same set of input matrices.
      A = np.array([[1,2,3],[4,5,6]])
      B = np.array([[1,2,3],[4,5,6]])
      C = np.array([[1.0000001,2,3],[4,5.00000001,6]]) 
    
      print('Matrix A:')
      print(A)
      print('Matrix B:')
      print(B)
      print('Matrix C:')
      print(C)
    
      print('Check for the equality of Matrices A and B:')
      print(np.array_equal(A,B))
    
      print('Check for the equality of Matrices A and C:')
      print(np.array_equal(A,C))

    Output:

      Matrix A:
      [[1 2 3]
       [4 5 6]]
      Matrix B:
      [[1 2 3]
       [4 5 6]]
      Matrix C:
      [[1.0000001  2.         3.  ]
       [4.         5.00000001 6.  ]]
      Check for the equality of Matrices A and B:
      True
      Check for the equality of Matrices A and C:
      False
  • numpy.allclose( )We can consider this function as the matrix level equivalent of the numpy.isclose( ) function.The numpy.allclose( ) function uses the same formula as the numpy.isclose( ) function.$$absolute(a – b) <= (atol + rtol * absolute(b))$$For example:
      A = np.array([[1,2,3],[4,5,6]])
      B = np.array([[1,2,3],[4,5,6]])
      C = np.array([[1.0000001,2,3],[4,5.00000001,6]]) 
    
      print('Matrix A:')
      print(A)
      print('Matrix B:')
      print(B)
      print('Matrix C:')
      print(C)
    
      print('Check for the equality of Matrices A and B:')
      print(np.allclose(A,B))
    
      print('Check for the equality of Matrices A and C:')
      print(np.allclose(A,C))

    Output:

      Matrix A:
      [[1 2 3]
       [4 5 6]]
      Matrix B:
      [[1 2 3]
       [4 5 6]]
      Matrix C:
      [[1.0000001  2.         3.  ]
       [4.         5.00000001 6.  ]]
      Check for the equality of Matrices A and B:
      True
      Check for the equality of Matrices A and C:
      True

    We can change the tolerance parameters (atol and rtol) according to our requirements.

    Check the article on Types of Matrices and the Github Repository to see the above two functions in action.

Addition and Subtraction of Matrices Using Python

The addition and subtraction of the matrices are the same as the scalar addition and subtraction operation. Therefore we can simply use the \(+\) and \(-\) operators to add and subtract two matrices.

$$
\begin{aligned}
A =
\begin{bmatrix}
1 & 3 & 5\\
7 & 9 & 11
\end{bmatrix}
\hspace{0.5cm}
&and
\hspace{0.5cm}
B =
\begin{bmatrix}
1 & 2 & 3\\
4 & 5 & 6
\end{bmatrix}\\[1em]
A+B =
\begin{bmatrix}
2 & 5 & 8\\
11 & 14 & 17
\end{bmatrix}
\hspace{0.5cm}
&and
\hspace{0.5cm}
A-B =
\begin{bmatrix}
0 & 1 & 2\\
3 & 4 & 5
\end{bmatrix}
\end{aligned}
$$

These are the element-wise operations in which the corresponding elements of the two matrices are added or subtracted to get the resulting matrices.

A = np.array([[1,3,5],[7,9,11]])
B = np.array([[1,2,3],[4,5,6]])

print('Matrix A:')
print(A)
print('Matrix B:')
print(B)

print('Matrix Addition:')
print(A+B)

print('Matrix Subtraction')
print(A-B)

Output:

Matrix A:
[[ 1  3  5]
 [ 7  9 11]]
Matrix B:
[[1 2 3]
 [4 5 6]]
Matrix Addition:
[[ 2  5  8]
 [11 14 17]]
Matrix Subtraction
[[0 1 2]
 [3 4 5]]

We can also use the numpy.add( ) and numpy.subtract( ) functions available in the NumPy library, if we want to have some added functionality.

These functions take two matrices to be added or subtracted as input.

A = np.array([[1,3,5],[7,9,11]])
B = np.array([[1,2,3],[4,5,6]])

print('Matrix A:')
print(A)
print('Matrix B:')
print(B)

print('Matrix Addition:')
print(np.add(A,B))

print('Matrix Subtraction')
print(np.subtract(A,B))

Output:

Matrix A:
[[ 1  3  5]
 [ 7  9 11]]
Matrix B:
[[1 2 3]
 [4 5 6]]
Matrix Addition:
[[ 2  5  8]
 [11 14 17]]
Matrix Subtraction
[[0 1 2]
 [3 4 5]]

Properties of Addition and Subtraction Operation Using Python

Now let’s extend our simple addition and subtraction program to check the validity of the properties stated previously.

  • Matrix addition is commutative.
      A = np.array([[1,3,5],[7,9,11]])
      B = np.array([[1,2,3],[4,5,6]])
    
      print('Matrix A:')
      print(A)
      print('Matrix B:')
      print(B)
    
      print('Matrix Addition (A + B):')
      print(A+B)
    
      print('Matrix Addition (B + A):')
      print(B+A)

    Output:

      Matrix A:
      [[ 1  3  5]
       [ 7  9 11]]
      Matrix B:
      [[1 2 3]
       [4 5 6]]
      Matrix Addition (A + B):
      [[ 2  5  8]
       [11 14 17]]
      Matrix Addition (B + A):
      [[ 2  5  8]
       [11 14 17]]

    Hence proved!

  • Addition and subtraction of matrices is associative
      A = np.array([[1,3,5],[7,9,11]])
      B = np.array([[1,2,3],[4,5,6]])
      C = np.array([[2,1,3],[3,2,1]])
    
      print('Matrix A:')
      print(A)
      print('Matrix B:')
      print(B)
      print('Matrix C:')
      print(C)
    
      print('Matrix Operation (A + B):')
      print((A + B))
      print('Matrix Operation (A + B) - C:')
      print((A + B) - C)   
      print('-------------------------')
      print('Matrix Operation (B - C):')
      print((B - C))
      print('Matrix Operation A + (B - C):')
      print(A + (B - C))

    Output:

      Matrix A:
      [[ 1  3  5]
       [ 7  9 11]]
      Matrix B:
      [[1 2 3]
       [4 5 6]]
      Matrix C:
      [[2 1 3]
       [3 2 1]]
      Matrix Operation (A + B):
      [[ 2  5  8]
       [11 14 17]]
      Matrix Operation (A + B) - C:
      [[ 0  4  5]
       [ 8 12 16]]
      -------------------------
      Matrix Operation (B - C):
      [[-1  1  0]
       [ 1  3  5]]
      Matrix Operation A + (B - C):
      [[ 0  4  5]
       [ 8 12 16]]

    It is quite intuitive to understand this property.

  • The Null Matrix (\(O\)) of the same order is an additive (and subtractive) identity.
      A = np.array([[1,2,3],[4,5,6]])
      O = np.zeros((2,3),dtype=int)
    
      print('Matrix A:')
      print(A)
      print('Matrix O:')
      print(O)
    
      print('Matrix Operation (A + O)')
      print(A + O)
      print('Matrix Operation (A - O)')
      print(A - O)

    Output:

      Matrix A:
      [[1 2 3]
       [4 5 6]]
      Matrix O:
      [[0 0 0]
       [0 0 0]]
      Matrix Operation (A + O)
      [[1 2 3]
       [4 5 6]]
      Matrix Operation (A - O)
      [[1 2 3]
       [4 5 6]]
  • The additive inverse of a matrixWe can get the additive inverse by reversing the sign of each element.
      A = np.array([[1,-2,3],[-4,5,-6]])
      B = -1*A
    
      print('Matrix A:')
      print(A)
      print('Matrix (-A):')
      print(B)
    
      print('Matrix Operation A + (-A)')
      print(A+B)

    Output:

      Matrix A:
      [[ 1 -2  3]
       [-4  5 -6]]
      Matrix (-A):
      [[-1  2 -3]
       [ 4 -5  6]]
      Matrix Operation A + (-A)
      [[0 0 0]
       [0 0 0]]

Multiply a Matrix by a Scalar in Python

As per the definition of multiplying a matrix by a scalar quantity, we need to multiply each element of the matrix by that scalar.

We can achieve this in the Python using the broadcasting functionality of the NumPy library.

A = np.array([[1,2,3],[4,5,6]])

print('Matrix A:')
print(A)

print('Matrix A multiplied by scalar:')
print(3*A)

Output:

Matrix A:
[[1 2 3]
 [4 5 6]]
Matrix A multiplied by scalar:
[[ 3  6  9]
 [12 15 18]]

Now, let’s validate the distributive property of the scalar multiplication operation with one example.

A = np.array([[1,2,3],[4,5,6]])
B = np.array([[1,3,5],[7,9,11]])
k = 3

print('Matrix A:')
print(A)
print('Matrix B:')
print(B)

print('Resultant matrix of kA + kB:')
print(k*A+k*B)
print('Resultant matrix of k(A+B):')
print(k*(A+B))

Output:

Matrix A:
[[1 2 3]
 [4 5 6]]
Matrix B:
[[ 1  3  5]
 [ 7  9 11]]
Resultant matrix of kA + kB:
[[ 6 15 24]
 [33 42 51]]
Resultant matrix of k(A+B):
[[ 6 15 24]
 [33 42 51]]

As you can see, both the resulting matrices are the same validating the distributive property.

Matrix Multiplication Using Python

Matrix multiplication is probably one of the most important matrix operations in linear algebra. We need to use matrix multiplication (or matrix product) in the case of solving the linear system of equations, while calculating the eigenvalues and eigenvectors, while obtaining the matrix decompositions.

With the powerful NumPy library, we can multiply two matrices with a single line of code using the numpy.matmul( ) function.

If you are using the Python version 3.5+, then you can use the *@* operator for the matrix multiplication.

A = np.array([[1,2,3],[4,5,6]])
B = np.array([[7,10],[8,11],[9,12]])

print('Matrix A (2x3):')
print(A)
print('Matrix B (3x2):')
print(B)    

print('Matrix multiplication AB (2x2):')
print(np.matmul(A,B))

print('Matrix multiplication BA (3x3):')
print(np.matmul(B,A))

print('-------------------------')
print('Matrix multiplication AB (2x2) using @ operator:')
print(A@B)

print('Matrix multiplication BA (3x3) using @ operator:')
print(B@A)

Output:

Matrix A (2x3):
[[1 2 3]
 [4 5 6]]
Matrix B (3x2):
[[ 7 10]
 [ 8 11]
 [ 9 12]]
Matrix multiplication AB (2x2):
[[ 50  68]
 [122 167]]
Matrix multiplication BA (3x3):
[[47 64 81]
 [52 71 90]
 [57 78 99]]
-------------------------
Matrix multiplication AB (2x2) using @  operator:
[[ 50  68]
 [122 167]]
Matrix multiplication BA (3x3) using @  operator:
[[47 64 81]
 [52 71 90]
 [57 78 99]]

Properties of Matrix Multiplication Using Python

Matrix multiplication operation has many interesting properties.

  • Matrix multiplication is NOT commutative.If any or both of the matrices are the Rectangular Matrices, then the product \(BA\) may or may not be defined, because the matrices might not be conformable.If both the matrices are the Square Matrices of the same order, then the product \(BA\) is always defined.Let’s see one example:
      A = np.array([[1,2,3],[4,5,6],[7,8,9]])
      B = np.array([[1,3,5],[7,9,11],[13,15,17]])
    
      print('Matrix A:')
      print(A)
      print('Matrix B:')
      print(B)
    
      print('Matrix product AB:')
      print(np.matmul(A,B))
      print('Matrix product BA:')
      print(np.matmul(B,A))

    Output:

      Matrix A:
      [[1 2 3]
       [4 5 6]
       [7 8 9]]
      Matrix B:
      [[ 1  3  5]
       [ 7  9 11]
       [13 15 17]]
      Matrix product AB:
      [[ 54  66  78]
       [117 147 177]
       [180 228 276]]
      Matrix product BA:
      [[ 48  57  66]
       [120 147 174]
       [192 237 282]]

    As we can observe that the products \(AB\) and \(BA\) are not equal.

  • Matrix multiplication is associative.The associativity of matrix multiplication is a very useful property.
      A = np.array([[1,2,3],[4,5,6]])
      B = np.array([[7,10],[8,11],[9,12]])
      C = np.array([[13],[14]])
      AB = np.matmul(A,B)
      BC = np.matmul(B,C)
    
      print('Matrix A (2x3):')
      print(A)
      print('Matrix B (3x2):')
      print(B)
      print('Matrix C (2x1):')
      print(C)        
    
      print('Matrix Product (AB)C (2x1):')
      print(np.matmul(AB,C))
      print('Matrix Product A(BC) (2x1):')
      print(np.matmul(A,BC))

    Output:

      Matrix A (2x3):
      [[1 2 3]
       [4 5 6]]
      Matrix B (3x2):
      [[ 7 10]
       [ 8 11]
       [ 9 12]]
      Matrix C (2x1):
      [[13]
       [14]]
      Matrix Product (AB)C (2x1):
      [[1602]
       [3924]]
      Matrix Product A(BC) (2x1):
      [[1602]
       [3924]]
  • Matrix multiplication is distributive.To use this property, make sure that all the corresponding matrices are conformable.
      A = np.array([1,2])
      B = np.array([[3,4],[5,6]])
      C = np.array([[7,8],[9,10]])
      AB = np.matmul(A,B)
      AC = np.matmul(A,C)
      BC = np.matmul(B,C)
    
      print('Matrix A (1x2):')
      print(A)
      print('Matrix B (2x2):')
      print(B)
      print('Matrix C (2x2):')
      print(C)        
    
      # Let's distribute the left multiplication    
    
      print('--------------------------------')
      print('Distributing left multiplication')
      print('Matrix Product A*(B + C) (1x2):')
      print(np.matmul(A,B+C))
      print('Matrix Product (AB + AC) (1x2):')
      print(AB+AC)
    
      # Similarly we can distribute the right multiplication
    
      print('--------------------------------')
      print('Distributing right multiplication')
      print('Matrix Product (A + B)*C (2x2):')
      print(np.matmul(A+B,C))
      print('Matrix Product (AC + BC) (2x2):')
      print(AC+BC)

    Output:

      Matrix A (1x2):
      [1 2]
      Matrix B (2x2):
      [[3 4]
       [5 6]]
      Matrix C (2x2):
      [[ 7  8]
       [ 9 10]]
      --------------------------------
      Distributing left multiplication
      Matrix Product A*(B + C) (1x2):
      [38 44]
      Matrix Product (AB + AC) (1x2):
      [38 44]
      --------------------------------
      Distributing right multiplication
      Matrix Product (A + B)*C (2x2):
      [[ 82  92]
       [114 128]]
      Matrix Product (AC + BC) (2x2):
      [[ 82  92]
       [114 128]]
  • Transpose of a matrix multiplicationIf \(AB\) is conformable then \(B^TA^T\) will also be conformable.
      A = np.array([1,2,3])
      B = np.array([[4,7],[5,8],[6,9]])
      AB = np.matmul(A,B)
    
      print('Matrix A (1x3):')
      print(A)
      print('Matrix B (3x2):')
      print(B)
    
      print('Transpose of matrix product AB:')
      print(AB.T)
    
      print('Product of B transpose and A transpose:')
      print(np.matmul(B.T,A.T))

    Output:

      Matrix A (1x3):
      [1 2 3]
      Matrix B (3x2):
      [[4 7]
       [5 8]
       [6 9]]
      Transpose of matrix product AB:
      [32 50]
      Product of B transpose and A transpose:
      [32 50]
  • Associativity of the product by a scalar quantity with the matrix multiplication
      A = np.array([[1,2],[3,4]])
      B = np.array([[5,6],[7,8]])
      AB = np.matmul(A,B)
      c = 2
    
      print('Matrix A:')
      print(A)
      print('Matrix B:')
      print(B)
    
      print('--------------------------------')
      print('Left associativity')
      print('Matrix operation c(AB):')
      print(c*AB)
      print('Matrix operation (cA)B:')
      print(np.matmul(c*A,B))
    
      print('--------------------------------')
      print('Right associativity')        
      print('Matrix operation (AB)c:')
      print(AB*c)
      print('Matrix operation A(Bc):')
      print(np.matmul(A,B*c))

    Output:

      Matrix A:
      [[1 2]
       [3 4]]
      Matrix B:
      [[5 6]
       [7 8]]
      --------------------------------
      Left associativity
      Matrix operation c(AB):
      [[ 38  44]
       [ 86 100]]
      Matrix operation (cA)B:
      [[ 38  44]
       [ 86 100]]
      --------------------------------
      Right associativity
      Matrix operation (AB)c:
      [[ 38  44]
       [ 86 100]]
      Matrix operation A(Bc):
      [[ 38  44]
       [ 86 100]]

    As you can see, the resulting matrices are equal.

  • The multiplicative identity \(I\), when multiplied with the matrix results in the original matrix.
      A = np.array([[1,2,3],[4,5,6]])
      (m,n) = np.shape(A)
      Im = np.eye(m,dtype=int)
      In = np.eye(n,dtype=int)
    
      print('Matrix A:')
      print(A)
      print('Matrix Im:')
      print(Im)
      print('Matrix In:')
      print(In)
    
      print('--------------------------------')
      print('Pre-multiplication by Im:')
      print(np.matmul(Im,A))
      print('--------------------------------')
      print('Post-multiplication by In:')
      print(np.matmul(A,In))

    Output:

      Matrix A:
      [[1 2 3]
       [4 5 6]]
      Matrix Im:
      [[1 0]
       [0 1]]
      Matrix In:
      [[1 0 0]
       [0 1 0]
       [0 0 1]]
      --------------------------------
      Pre-multiplication by Im:
      [[1 2 3]
       [4 5 6]]
      --------------------------------
      Post-multiplication by In:
      [[1 2 3]
       [4 5 6]]

    Here \(Im\) and \(In\) are Identity Matrices.

Raise a Matrix to a Power Using Python

The matrix should be a Square Matrix, i.e., the number of rows should be equal to the number of columns, to be able to calculate the power of the matrix.

We have two methods available to calculate the power of a matrix. The first method is to use the numpy.matmul( ) function.

A = np.array([[1,2,3],[4,5,6],[7,8,9]])
A_sq = np.matmul(A,A)
A_cube = np.matmul(A,A_sq)

print('Matrix A:')
print(A)
print('Square of Matrix A:')
print(A_sq)
print('Cube of Matrix A:')
print(A_cube)

Output:

Matrix A:
[[1 2 3]
 [4 5 6]
 [7 8 9]]
Square of Matrix A:
[[ 30  36  42]
 [ 66  81  96]
 [102 126 150]]
Cube of Matrix A:
[[ 468  576  684]
 [1062 1305 1548]
 [1656 2034 2412]]

But this method becomes repetitive and tedious if we want to raise the matrix to a higher power.

In this case, the second method is more elegant and efficient, which uses the numpy.linalg.matrix_power( ) from the NumPy library.

A = np.array([[1,2,3],[4,5,6],[7,8,9]])

print('Matrix A:')
print(A)
print('Square of Matrix A:')
print(np.linalg.matrix_power(A,2))
print('Cube of Matrix A:')
print(np.linalg.matrix_power(A,3))
print('Sixth power of Matrix A:')
print(np.linalg.matrix_power(A,6))

Output:

Matrix A:
[[1 2 3]
 [4 5 6]
 [7 8 9]]
Square of Matrix A:
[[ 30  36  42]
 [ 66  81  96]
 [102 126 150]]
Cube of Matrix A:
[[ 468  576  684]
 [1062 1305 1548]
 [1656 2034 2412]]
Sixth power of Matrix A:
[[ 1963440  2412504  2861568]
 [ 4446414  5463369  6480324]
 [ 6929388  8514234 10099080]]

Properties of the Power of a Matrix Using Python

All the properties of the power of the matrix are discussed in detail in the article on types of matrices.

Did you find this article useful? Please comment and share it with your friends. Please let me know, if there are any suggestions or queries regarding the content of this article.

Leave a Reply