C++ 中的两个矩阵相乘

Jinku Hu 2023年10月12日
C++ 中的两个矩阵相乘

本文将介绍几种在 C++ 中如何将两个矩阵相乘的方法。

在 C++ 中使用串行实现两个矩阵相乘

矩阵乘法是广泛的工程解决方案中最常用的运算之一。因此,存在各种算法来提高不同硬件平台上的性能。这些算法通常利用并发编程以及矩阵平铺来加速矩阵乘法。不过,在这种情况下,我们实现了一种简单的算法,该算法无需任何显式优化即可连续执行。

首先,我们需要实现一些实用程序功能,以帮助分配和初始化要使用的矩阵。请注意,我们正在执行代码,以便程序员可以修改 ROWCOL 常量整数以指定矩阵尺寸。allocateMatrix 函数分配数组,并用零值初始化元素。接下来,调用 initilizeMatrix 函数,该函数生成范围为 [0, 100) 的随机数,并将其存储为矩阵元素。注意,还有一个函数可以将矩阵元素打印到 cout 流中,以验证计算结果。

multiplyMatrix 函数实现了一个简单的三嵌套 for 循环,以将两个矩阵相乘并将结果存储在预分配的第三个矩阵中。结果矩阵尺寸取自第一矩阵行和第二矩数组。请注意,循环顺序对于乘法性能非常重要。例如,如果我们在中间移动最里面的 for 语句,则可以保证几乎可以保证性能提高。性能的提高是由于几乎每个现代 CPU 中都装有高速缓存。高速缓存内存比主内存快,并且在检索数据时它会存储连续的内存块。因此,下一次数据检索可以从缓存本身进行服务。

#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;
}

输出:

83;    86;    77;
15;    93;    35;

86;    92;
49;    21;
62;    27;

16126; 11521;
8017;  4278;

最后,重要的是在程序退出之前释放矩阵使用的所有内存资源。实现了 deallocateMatrix 函数,以便它使用矩阵指针和其中的行来删除对象中的每个元素。注意,在 multiplyMatrix 函数作用域中分配的结果矩阵也应显式释放。

作者: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 创始人。Jinku 在机器人和汽车行业工作了8多年。他在自动测试、远程测试及从耐久性测试中创建报告时磨练了自己的编程技能。他拥有电气/电子工程背景,但他也扩展了自己的兴趣到嵌入式电子、嵌入式编程以及前端和后端编程。

LinkedIn Facebook

相关文章 - C++ Math