簡體   English   中英

矩陣乘法作為列主要

[英]matrix multiplication as column major

我試圖成為列專業,我似乎無法找到正確的公式! 我希望矩陣為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;
...

我不想轉置矩陣然后使用行專業。

我想將數據作為專欄處理。

因為索引(如果作為列主要存儲)將是不同的(因此,為了進行乘法將很重要)。

有兩件事會導致你的困惑。

首先,您所連續的一維向量中的數據不是按照主要順序排列,而是按行主順序排列 ,就像C中二維連續數組的常規布局一樣。線性一維指數在具有M行和N列( M × N )的矩陣中的行i和列j是:

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的列數是rows

實際上,當將M × L矩陣AL × N矩陣B相乘以得到M × N矩陣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
                   |

括號中的字母是下面的代碼用於迭代相應維度的變量。

現在,您可以以行主格式乘以矩陣:

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

或以列主格式:

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

輸入和輸出都在各自的矩陣表示中,當然在兩種情況下不同。

你有什么想法

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

它會做什么?

ik變為1並且j變為2時,它將訪問數組res, AB res, A

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM