
Transpose
The transpose of matrix M, written as is a matrix in which every element i, j equals the element j, i of the original matrix. The transpose of a matrix can be acquired by reflecting the matrix over its main diagonal, writing the rows of M as the columns of
, or by writing the columns of M as the rows of
. We can express the transpose for each component of a matrix with the following equation:

The transpose operation replaces the rows of a matrix with its columns:
Getting ready
We're going to create a non-nested loop that serves as a generic Transpose
function. This function will be able to transpose matrices of any dimension. We're then going to create Transpose
functions specific to 2 X 2, 3 X 3, and 4 X 4 matrices. These more specific functions are going to call the generic Transpose
with the appropriate arguments.
How to do it…
Follow these steps to implement a generic transpose function and transpose functions for two, three and four dimensional square matrices:
- Add the declarations for all of the
Transpose
function tomatrices.h
:void Transpose(const float *srcMat, float *dstMat, int srcRows, int srcCols); mat2 Transpose(const mat2& matrix); mat3 Transpose(const mat3& matrix); mat4 Transpose(const mat4& matrix);
- Create a new file,
matrices.cpp
. In this file, include thecmath
,cfloat
, andmatrices.h
headers. Also, include a copy of theCMP
macro we used invectors.cpp
:#include "matrices.h" #include <cmath> #include <cfloat> #define CMP(x, y) \ (fabsf((x) – (y)) <= FLT_EPSILON * \ fmaxf(1.0f, fmaxf(fabsf(x), fabsf(y))))
- Implement the generic transpose function in
matrices.cpp
:void Transpose(const float *srcMat, float *dstMat, int srcRows, int srcCols) { for (int i = 0; i < srcRows * srcCols; i++) { int row = i / srcRows; int ccl = i % srcRows; dstMat[i] = srcMat[srcCols * col + row]; } }
- Using the generic
Transpose
function, implementTranspose
for 2 X 2, 3 X 3, and 4 X 4 matrices inmatrices.cpp
:mat2 Transpose(const mat2& matrix) { mat2 result; Transpose(matrix.asArray, result.asArray, 2, 2); return result; } mat3 Transpose(const mat3& matrix) { mat3 result; Transpose(matrix.asArray, result.asArray, 3, 3); return result; } mat4 Transpose(const mat4& matrix) { mat4 result; Transpose(matrix.asArray, result.asArray, 4, 4); return result; }
How it works…
Let's explore how the generic version of Transpose
works by examining how a single element is transposed. Assume we have the following 4 X 4 matrix:

We're going to find the transpose of the element in row 3, column 4; it has the value L. If we access the matrix as an array, the linear index of L is 11. Let's explore how the generic Transpose
loop works when i == 11
.
First, the values of row and col are calculated. To calculate the row of the element: row = i / srcRows
, substitute 11
for i
, this becomes row = 11 / 4
. C++ integer division truncates the result towards 0, therefore row = 2
. Remember the array is indexed starting at 0 not 1, meaning the row at index 2 is actually the third row. The column is calculated using the modulo operator col = i % srcRows
, substituting the variables becomes col = 11 % 4
. The result of this operation is 3. Again, the column at index 3 is actually the 4th column, and this is the expected behavior.
We index the source array using [srcCols * col + row]
, substituting the variables, this becomes [4 * 3 + 2].
The result is index 14. The element in the original matrix at index 14 is element O, the transpose of L.
To index the original element, L, we would change the index calculation to [srcCols * row + col]
. To access the transpose of the element, all we had to do was switch the row
and col
variables.