在C中将较大的矩阵乘以一个小矩阵
我有一个4 * 4的矩阵,我想把它分成4 * 2 * 2矩阵块,以便我可以乘以不同的2 * 2矩阵。 我如何在C中做到这一点?
A = [1 2 3 4; 2 3 4 5; 3 4 5 6; 4 5 6 7]
B = [2 3; 4 5]
我知道矩阵形式来自MATLAB,但在这里编写它就更容易。
如果你不清楚,我想把B乘以A的4个不同的块,即[1 2; 2 3],[3 4; 4 5],[3 4; 4 5]和[5 6; 6 7] ...
以下是我迄今为止所做的结果导致了糟糕的答案:
for (i = 1; i<= 4; i++)
{
for (j = 1; j<=4; j++)
{
C[i][j] = A[i][j]*B[i-2][j-2];
}
}
我假设你想这样做,你是否写过一个MATLAB脚本。
A11 = [11, 12; 21, 22];
A12 = [13, 14; 23, 24];
A21 = [31, 32; 41, 42];
A22 = [33, 34; 43, 44];
A = [A11, A12; A21, A22]
B = [11, 12; 21, 22]
C = [A11 * B, A12 * B; A21 * B, A22 * B]
如果我通过GNU Octave运行脚本 - 我推荐它作为MATLAB的一个基本兼容的免费软件替代品 - 它会产生以下输出:
A =
11 12 13 14
21 22 23 24
31 32 33 34
41 42 43 44
B =
11 12
21 22
C =
373 396 437 464
693 736 757 804
1013 1076 1077 1144
1333 1416 1397 1484
那么让我们看看如何在C中完成它。
#include <stdio.h>
int
main()
{
int i, j;
int A[4][4] = {
{11, 12, 13, 14},
{21, 22, 23, 24},
{31, 32, 33, 34},
{41, 42, 43, 44},
};
int B[2][2] = {
{11, 12},
{21, 22},
};
int C[4][4] = {
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
for (i = 0; i < 4; i += 2)
{
for (j = 0; j < 4; j += 2)
{
/* For each 2 x 2 block with upper-left corner at (i, j). */
C[i + 0][j + 0] = A[i + 0][j + 0] * B[0][0] + A[i + 0][j + 1] * B[1][0];
C[i + 0][j + 1] = A[i + 0][j + 0] * B[0][1] + A[i + 0][j + 1] * B[1][1];
C[i + 1][j + 0] = A[i + 1][j + 0] * B[0][0] + A[i + 1][j + 1] * B[1][0];
C[i + 1][j + 1] = A[i + 1][j + 0] * B[0][1] + A[i + 1][j + 1] * B[1][1];
}
}
for (i = 0; i < 4; ++i)
printf("%8d%8d%8d%8dn", C[i][0], C[i][1], C[i][2], C[i][3]);
return 0;
}
假设你知道线性代数的要点,我不认为该程序将需要更多的解释。 我把它作为一个练习来找出最内层循环中的模式,并将它重写为两个更多的嵌套循环。 如果你的矩阵真的只是2×2,那么像这样硬编码索引可能是编写程序最可读的方式。 随着矩阵变大,你真的需要一个循环。
C程序的输出是
373 396 437 464
693 736 757 804
1013 1076 1077 1144
1333 1416 1397 1484
这恰好被GNU Octave脚本确认。
对于这样的小矩阵来说,性能几乎肯定不是问题。 如果你正在处理更大的矩阵,你应该使用专门的库,例如(C)BLAS来进行线性代数计算。 BLAS界面的学习曲线有点陡峭,使用起来不方便。 如果您有机会使用C ++进行编程,则有更多表现力强大的库(如Eigen)可以实现可比较的性能。
链接地址: http://www.djcxy.com/p/85987.html