矩阵乘法作为列专业

Geo*_*rge 1 c c++

我正在尝试乘以列专业,但似乎找不到正确的公式!我想将矩阵设为 1D。

假设我有这些矩阵:

A=

1 3

2 4

和 B=

5 2 1

6 3 7

假设上述矩阵已按列主要顺序存储。

我在尝试:

int main(int argc, const char* argv[]) {
  int rows=2;
  int cols=3;


  int A[rows*rows];
  int B[rows*cols];
  int res[rows*cols];

  A[0]=1;
  A[1]=3;
  A[2]=2;
  A[3]=4;


  B[0]=5;
  B[1]=2;
  B[2]=1;
  B[3]=6;
  B[4]=3;
  B[5]=7;

  /*A[0]=1;
  A[1]=2;
  A[2]=3;
  A[3]=4;


  B[0]=5;
  B[1]=6;
  B[2]=2;
  B[3]=3;
  B[4]=1;
  B[5]=7;
  */


  //multiplication as column major
 for (int i=0;i<rows;i++){
   for (int j=0;j<cols;j++){
     res[i+j*rows]=0;
     for (int k=0;k<rows;k++){
    res[i+j*rows]+=A[i+k*rows]*B[k+j*cols];


   }

   }
}



  for (int i=0;i<rows*cols;i++){
     printf("\n\nB[%d]=%d\t",i,res[i]);

  }

  return 0; 

 }
Run Code Online (Sandbox Code Playgroud)

我没有得到正确的结果。

另外,我无法理解(在矩阵已经存储在主列中的情况下),如何索引矩阵 A 和 B。

 A[0]=1;

 A[1]=3;

...
Run Code Online (Sandbox Code Playgroud)

或者

  A[0]=1;

  A[1]=2;
...
Run Code Online (Sandbox Code Playgroud)

我不想转置矩阵然后使用行专业。

我想将数据作为列专业处理。

因为索引,如果存储为主要列,将会不同(因此,为了进行乘法会很重要)。

M O*_*ehm 6

有两件事会导致您在这里感到困惑。

首先,连续一维向量中的数据不是如你所说的列优先顺序,而是行优先顺序,就像 C 中二维连续数组的通常布局一样。 的线性一维索引行i和列j与矩阵M的行和N列(MX N)为:

A[i*N + j]      // row major
A[i + M*j]      // column major
Run Code Online (Sandbox Code Playgroud)

“主要”是指在使用两个嵌套循环顺序遍历数组时外循环的维度:

n = 0;
for (i = 0; i < M; i++) {
    for (j = 0; j < N; j++) {
        printf("%8d", A[n++]);
    }
    printf("\n");
}
Run Code Online (Sandbox Code Playgroud)

其次,您使用两个维度rowscolumnswhich 是结果矩阵的维度,这令人困惑,因为其中的列数Arows

事实上,当您将MxL矩阵ALxN矩阵相乘B以获得MxN矩阵时,矩阵乘法涉及三个不同的维度C。在你的情况,ML恰巧是两个2:

           L (k)   |     N (j)
                   |
                   |   5   2   1
   L (k)           |
                   |   6   3   7
                   |
  -----------------+-------------
                   |
            1   3  |  23  11  22
   M (i)           |
            2   4  |  34  16  30
                   |
Run Code Online (Sandbox Code Playgroud)

括号中的字母是以下代码用于迭代各个维度的变量。

现在您可以将矩阵乘以行主格式:

    #define M 2
    #define N 3
    #define L 2

    int A[M * L] = {1, 3, 2, 4};
    int B[L * N] = {5, 2, 1, 6, 3, 7};
    int res[M * N];

    int i, j, k;

    for (i = 0; i < M; i++) {
        for (j = 0; j < N; j++) {
            res[j + i * N] = 0;

            for (k = 0; k < L; k++) {
                res[j + i * N] += A[k + i * L] * B[j + k * N];
            }
        }
    }

    for (i = 0; i < M * N; i++) printf("[%d] = %d\n", i, res[i]);
Run Code Online (Sandbox Code Playgroud)

或以列主要格式:

    #define M 2
    #define N 3
    #define L 2

    int A[M * L] = {1, 2, 3, 4};
    int B[L * N] = {5, 6, 2, 3, 1, 7};
    int res[M * N];

    int i, j, k;

    for (i = 0; i < M; i++) {
        for (j = 0; j < N; j++) {
            res[j * M + i] = 0;

            for (k = 0; k < L; k++) {
                res[j * M + i] += A[k * M + i] * B[j * L + k];
            }
        }
    }

    for (i = 0; i < M * N; i++) printf("[%d] = %d\n", i, res[i]);
Run Code Online (Sandbox Code Playgroud)

输入和输出都在各自的矩阵表示中,当然这两种情况是不同的。