[英]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.