Multiplique duas matrizes em C++
Este artigo explicará vários métodos de como multiplicar duas matrizes em C++.
Use a implementação serial para multiplicar duas matrizes em C++
A multiplicação de arrayes é uma das operações mais comumente usadas em uma ampla gama de soluções de engenharia. Assim, existem vários algoritmos para melhorar o desempenho em diferentes plataformas de hardware. Esses algoritmos geralmente utilizam programação simultânea, bem como tiling de array para acelerar a multiplicação de arrayes. Nesse caso, porém, implementamos um algoritmo direto que é executado em série sem nenhuma otimização explícita.
Primeiramente, precisamos implementar algumas funções utilitárias para ajudar a alocar e inicializar matrizes com as quais operar. Observe que estamos implementando o código para que o programador possa modificar os inteiros constantes ROW
e COL
para especificar as dimensões do array. A função allocateMatrix
aloca o array de arrays e inicializa os elementos com valores zero. Em seguida, a função initilizeMatrix
é chamada e gera números aleatórios no intervalo - [0, 100)
e os armazena como elementos de array. Observe que também há uma função que imprime os elementos do array no fluxo cout
para verificar os resultados do cálculo.
A função multiplyMatrix
implementa um loop for
aninhado triplo simples para multiplicar duas matrizes e armazenar os resultados na terceira matriz pré-alocada. As dimensões do array de resultado são obtidas das primeiras linhas do array e das segundas colunas do array. Lembre-se de que a ordem do loop é muito importante para o desempenho da multiplicação. Por exemplo, se movermos a instrução for
mais interna no meio, há um aumento de desempenho quase garantido esperado. A melhoria de desempenho é causada pelas memórias cache que estão localizadas em quase todas as CPUs contemporâneas. A memória cache é mais rápida do que a memória principal e armazena blocos de memória contíguos quando os dados são recuperados. Assim, a próxima recuperação de dados pode ser servida a partir dos próprios caches.
#include <iomanip>
#include <iostream>
#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;
}
Resultado:
83; 86; 77;
15; 93; 35;
86; 92;
49; 21;
62; 27;
16126; 11521;
8017; 4278;
Finalmente, é importante liberar todos os recursos de memória usados pelas matrizes antes de encerrar o programa. A função deallocateMatrix
é implementada de forma que pegue um ponteiro de array e linhas nele para excluir cada elemento no objeto. Observe que a matriz de resultados alocada no escopo da função multiplicaçãoMatriz
também deve ser desalocada explicitamente.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook