![](/img/trans.png)
[英]GLM - Matrix from orientation is creating row major and not column major matrix?
[英]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");
}
其次,使用兩個維度的rows
和columns
,它們是結果矩陣的維度,這是令人困惑的,因為A
的列數是rows
。
實際上,當將M
× L
矩陣A
與L
× N
矩陣B
相乘以得到M
× N
矩陣C
時,矩陣乘法中涉及三個不同的維度。 在你的情況下, M
和L
碰巧都是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];
它會做什么?
當i
和k
變為1
並且j
變為2
時,它將訪問數組res, A
和B
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.