我正在尝试乘以列专业,但似乎找不到正确的公式!我想将矩阵设为 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;
}
Run Code Online (Sandbox Code Playgroud)
我没有得到正确的结果。
另外,我无法理解(在矩阵已经存储在主列中的情况下),如何索引矩阵 A 和 B。
A[0]=1;
A[1]=3;
...
Run Code Online (Sandbox Code Playgroud)
或者
A[0]=1;
A[1]=2;
...
Run Code Online (Sandbox Code Playgroud)
我不想转置矩阵然后使用行专业。
我想将数据作为列专业处理。
因为索引,如果存储为主要列,将会不同(因此,为了进行乘法会很重要)。
有两件事会导致您在这里感到困惑。
首先,连续一维向量中的数据不是如你所说的列优先顺序,而是行优先顺序,就像 C 中二维连续数组的通常布局一样。 的线性一维索引行i和列j与矩阵M的行和N列(MX N)为:
A[i*N + j] // row major
A[i + M*j] // column major
Run Code Online (Sandbox Code Playgroud)
“主要”是指在使用两个嵌套循环顺序遍历数组时外循环的维度:
n = 0;
for (i = 0; i < M; i++) {
for (j = 0; j < N; j++) {
printf("%8d", A[n++]);
}
printf("\n");
}
Run Code Online (Sandbox Code Playgroud)
其次,您使用两个维度rows,columnswhich 是结果矩阵的维度,这令人困惑,因为其中的列数A是rows。
事实上,当您将MxL矩阵A 与LxN矩阵相乘B以获得MxN矩阵时,矩阵乘法涉及三个不同的维度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
|
Run Code Online (Sandbox Code Playgroud)
括号中的字母是以下代码用于迭代各个维度的变量。
现在您可以将矩阵乘以行主格式:
#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]);
Run Code Online (Sandbox Code Playgroud)
或以列主要格式:
#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]);
Run Code Online (Sandbox Code Playgroud)
输入和输出都在各自的矩阵表示中,当然这两种情况是不同的。