C++에서 두 행렬 곱하기

Jinku Hu 2023년10월12일
C++에서 두 행렬 곱하기

이 기사에서는 C++에서 두 행렬을 곱하는 방법에 대한 몇 가지 방법을 설명합니다.

직렬 구현을 사용하여 C++에서 두 행렬 곱하기

행렬 곱셈은 광범위한 엔지니어링 솔루션에서 가장 일반적으로 사용되는 작업 중 하나입니다. 따라서 다양한 하드웨어 플랫폼에서 성능을 향상시키는 다양한 알고리즘이 있습니다. 이러한 알고리즘은 종종 동시 프로그래밍과 행렬 타일링을 활용하여 행렬 곱셈을 가속화합니다. 하지만이 경우 명시적인 최적화없이 직렬로 실행되는 간단한 알고리즘을 구현합니다.

처음에는 작업 할 행렬을 할당하고 초기화하는 데 도움이되는 몇 가지 유틸리티 함수를 구현해야합니다. 프로그래머가 행렬 차원을 지정하기 위해ROWCOL상수 정수를 수정할 수 있도록 코드를 구현하고 있음을 유의하십시오. allocateMatrix함수는 배열의 배열을 할당하고 0 값으로 요소를 초기화합니다. 다음으로[0, 100)범위의 난수를 생성하고이를 행렬 요소로 저장하는initilizeMatrix함수가 호출됩니다. 계산 결과를 확인하기 위해 행렬 요소를cout스트림에 인쇄하는 함수도 있습니다.

multiplyMatrix함수는 간단한 3 중 중첩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

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

관련 문장 - C++ Math