# Multiply Two Matrices in C++

This article will explain several methods of how to multiply two matrices in C++.

## Use Serial Implementation to Multiply Two Matrices in C++

Matrix multiplication is one of the most commonly used operations across a wide range of engineering solutions. Thus, there are various algorithms to improve the performance on different hardware platforms. These algorithms often utilize concurrent programming as well as matrix tiling to accelerate matrix multiplication. In this case, though, we implement a straightforward algorithm that executes serially without any explicit optimizations.

At first, we need to implement some utility functions to help allocate and initialize matrices to operate with. Note that we are implementing the code so that the programmer can modify `ROW`

and `COL`

constant integers to specify the matrix dimensions. `allocateMatrix`

function allocates the array of arrays and initializes elements with zero values. Next, `initilizeMatrix`

function is called that generates random numbers in range - `[0, 100)`

and stores them as matrix elements. Notice that there’s also a function that prints the matrix elements to the `cout`

stream to verify the calculation results.

The `multiplyMatrix`

function implements a simple triple-nested `for`

loop to multiply two matrices and store the results in the preallocated third matrix. The result matrix dimensions are taken from the first matrix rows and the second matrix columns. Mind that, the loop order is quite important for the multiplication performance. E.g., if we move the innermost `for`

statement in the middle, there’s an almost guaranteed performance boost expected. The performance improvement is caused by the cache memories that are located in almost every contemporary CPU. Cache memory is faster than the main memory, and it stores contiguous memory blocks when the data is retrieved. Thus, the next data retrieval can be served from caches themselves.

```
#include <iostream>
#include <iomanip>
#include <vector>
using std::cout; using std::endl;
using std::setw; using std::vector;
constexpr int ROW = 2;
constexpr int COL = 3;
void initilizeMatrix(int **m, int row, int col)
{
for(auto i = 0; i < row; ++i) {
for(auto j = 0; j < col; ++j) {
m[i][j] = rand() % 100;
}
}
}
void printMatrix(int **m, int row, int col)
{
for(auto i = 0; i < row; ++i) {
for(auto j = 0; j < col; ++j) {
cout << setw(5) << m[i][j] << "; ";
}
cout << endl;
}
}
int **allocateMatrix(int row, int col)
{
int **matrix = new int*[row];
for(int i = 0; i < row; ++i) {
matrix[i] = new int[col]{0};
}
return matrix;
}
int deallocateMatrix(int **matrix, int row)
{
for(int i = 0; i < row; ++i) {
delete matrix[i];
}
delete [] matrix;
return 0;
}
int **multiplyMatrix(int **m1, int row1, int col1, int **m2, int row2, int col2)
{
if (col1 != row2)
return nullptr;
auto ret = allocateMatrix(row1, col2);
int i,j,k;
for(i = 0; i < row1; i++) {
for(j = 0; j < col2; j++) {
for(k = 0; k < col1; k++) {
ret[i][j] += m1[i][k] * m2[k][j];
}
}
}
return ret;
}
int main(){
int **matrix1 = allocateMatrix(ROW, COL);
int **matrix2 = allocateMatrix(COL, ROW);
initilizeMatrix(matrix1, ROW, COL);
initilizeMatrix(matrix2, COL, ROW);
printMatrix(matrix1, ROW, COL);
cout << endl;
printMatrix(matrix2, COL, ROW);
auto result = multiplyMatrix(matrix1, ROW, COL, matrix2, COL, ROW);
cout << endl;
printMatrix(result, ROW, ROW);
deallocateMatrix(matrix1, ROW);
deallocateMatrix(matrix2, COL);
deallocateMatrix(result, ROW);
return EXIT_SUCCESS;
}
```

Output:

```
83; 86; 77;
15; 93; 35;
86; 92;
49; 21;
62; 27;
16126; 11521;
8017; 4278;
```

Finally, it’s important to free all the memory resources used by the matrices before the program exits. `deallocateMatrix`

function is implemented so that it takes a matrix pointer and rows in it to delete each element in the object. Notice that the result matrix allocated in the `multiplyMatrix`

function scope should also be deallocated explicitly.