
Multiplication
Like a vector, there are many ways to multiply a matrix. In this chapter we will cover multiplying matrices by a scalar or by another matrix. Scalar multiplication is component wise. Given a matrix M and a scalar s, scalar multiplication is defined as follows:

We can also multiply a matrix by another matrix. Two matrices, A and B, can be multiplied together only if the number of columns in A matches the number of rows in B. That is, two matrices can only be multiplied together if their inner dimensions match.
When multiplying two matrices together, the dimension of the resulting matrix will match the outer dimensions of the matrices being multiplied. If A is an matrix and B is an
matrix, the product of AB will be an
matrix. We can find each element of the matrix AB with the following formula:

This operation concatenates the transformations represented by the two matrices into one matrix. Matrix multiplication is not cumulative. . However, matrix multiplication is associative, meaning
.
Getting ready
Just as with the Transpose
operation, we're going to write a generic matrix multiplication function that works on arrays representing matrices of any size. Then, we're going to call this generic matrix multiply function from operator overrides for mat2
, mat3
, and mat4
.
How to do it…
Follow these steps to implement scalar multiplication for two, three and four dimensional square matrices:
- We're going to start with scalar multiplication. First, add the declaration for scalar multiplication to
matrices.h
.:mat2 operator*(const mat2& matrix, float scalar); mat3 operator*(const mat3& matrix, float scalar); mat4 operator*(const mat4& matrix, float scalar);
- Next, add the implementation for the scalar multiplication functions to
matrices.cpp
:mat2 operator*(const mat2& matrix, float scalar) { mat2 result; for (int i = 0; i < 4; ++i) { result.asArray[i] = matrix.asArray[i] * scalar; } return result; } mat3 operator*(const mat3& matrix, float scalar) { mat3 result; for (int i = 0; i < 9; ++i) { result.asArray[i] = matrix.asArray[i] * scalar; } return result; } mat4 operator*(const mat4& matrix, float scalar) mat4 result; for (int i = 0; i < 16; ++i) { result.asArray[i] = matrix.asArray[i] * scalar; } return result; }
- Now it's time to implement matrix-matrix multiplication. First, add the declaration for the generic matrix
Multiply
function and the overridden matrix multiplication operators tomatrices.h
. The genericMultiply
function returns a Boolean value because the operation can fail. Matrix multiplication fails if the inner dimensions of the matrices being multiplied are not the same:bool Multiply(float* out, const float* matA, int aRows, int aCols, const float* matB, int bRows, int bCols); mat2 operator*(const mat2& matA, const mat2& matB); mat3 operator*(const mat3& matA, const mat3& matB); mat4 operator*(const mat4& matA, const mat4& matB);
- Implement the generic
Multiply
function inmatrices.cpp
:bool Multiply(float* out, const float* matA, int aRows, int aCols, const float* matB, int bRows, int bCols) { if (aCols != bRows) { return false; } for (int i = 0; i < aRows; ++i) { for (int j = 0; j < bCols; ++j) { out[bCols * i + j] = 0.0f; for (int k = 0; k < bRows; ++k) { int a = aCols * i + k; int b = bCols * k + j; out[bCols * i + j] += matA[a] * matB[b]; } } } return true; }
- Implement the overridden matrix multiplication operators in
matrices.cpp
. These operators are going to call the genericMultiply
function with the proper arguments:mat2 operator*(const mat2& matA, const mat2& matB) { mat2 res; Multiply(res.asArray, matA.asArray, 2, 2, matB.asArray, 2, 2); return res; } mat3 operator*(const mat3& matA, const mat3& matB) { mat3 res; Multiply(res.asArray, matA.asArray, 3, 3, matB.asArray, 3, 3); return res; } mat4 operator*(const mat4& matA, const mat4& matB) { mat4 res; Multiply(res.asArray, matA.asArray, 4, 4, matB.asArray, 4, 4); return res; }
How it works…
It may not be obvious from the preceding code but, when multiplying matrices A and B, each element i, j of the result is the dot product of row i from matrix A and column j from matrix B:

This figure demonstrates finding element 3,2 when multiplying matrices A and B. To find element 3,2 we take the dot product of row 3 from matrix A and column 2 from matrix B.
This is why the inner dimensions of the two matrices being multiplied together must match, so we take the dot product of vectors that have the same size.