我正试图成为专业大师,我似乎找不到合适的公式! 我想把矩阵作为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;
...
我不想转置矩阵,然后使用行专业。
我想将数据作为专栏处理。
因为索引(如果作为列主要存储)将是不同的(因此,为了进行乘法,这很重要)。
答案 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");
}
其次,您使用两个维度rows
和columns
这两个维度是结果矩阵的维度,这会令人困惑,因为A
中的列数为{{1} }。
事实上,当您将rows
x M
矩阵L
与A
x L
矩阵相乘时,矩阵乘法涉及三个不同的维度N
获得B
x M
矩阵N
。在您的情况下,C
和M
恰好都是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, A
和B
变为i
且k
变为1
时,它将访问数组j
和2
。 }。
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];