矩阵乘法作为列主要

时间:2014-03-03 11:03:21

标签: 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; 

 }

我没有得到正确的结果。

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

 A[0]=1;

 A[1]=3;

...

  A[0]=1;

  A[1]=2;
...

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

我想将数据作为专栏处理。

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

2 个答案:

答案 0 :(得分:3)

有两件事会导致你的困惑。

首先,您所连续的一维向量中的数据不是按照主要顺序排列,而是在row-major order中,与C中二维连续数组的常规布局一样。包含i行和j列(M x N)的矩阵中的行M和列N的维度索引为:< / p>

A[i*N + j]      // row major
A[i + M*j]      // column major

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

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

其次,您使用两个维度rowscolumns这两个维度是结果矩阵的维度,这会令人困惑,因为A中的列数为{{1} }。

事实上,当您将rows x M矩阵LA x L矩阵相乘时,矩阵乘法涉及三个不同的维度N获得B x M矩阵N。在您的情况下,CM恰好都是2:

L

括号中的字母是下面的代码用于迭代相应维度的变量。

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

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

或以列式主要格式:

    #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]);

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

答案 1 :(得分:0)

您如何看待

res[i+j*rows]+=A[i+k*rows]*B[k+j*cols];  

它会做什么?

res, AB变为ik变为1时,它将访问数组j2。 }。

res[1+2*2]+=A[1+1*2]*B[1+2*3] = res[5]+=A[4]*B[7];  

这将调用未定义的行为,您可能会得到预期或意外的结果。

我认为你需要这个:

res[i*rows+j] += A[i*rows + k] * B[j + k*cols];