Multiplying a small matrix inside a bigger matrix in C
I have a 4*4 matrix and I want to divide it into 4 blocks of 2*2 matrices so that I can multiply them by a different 2*2 matrix. How do I do that in C?
A = [1 2 3 4; 2 3 4 5; 3 4 5 6; 4 5 6 7]
B = [2 3; 4 5]
I know the matrix form is from MATLAB but it's just easier to write it that way here.
Just in case you weren't clear, I wanted to multiply B, into the 4 different blocks of A, namely [1 2; 2 3], [3 4; 4 5], [3 4; 4 5] and [5 6 ;6 7]...
Here's what I've done so far that has resulted in crappy answers:
for (i = 1; i<= 4; i++)
{
for (j = 1; j<=4; j++)
{
C[i][j] = A[i][j]*B[i-2][j-2];
}
}
I assume that you wanted to do this, had you been writing a MATLAB script.
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]
If I run the script through GNU Octave – which I recommend as a largely compatible free software replacement for MATLAB – it produces the following output:
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
So let's see how it can be done in 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;
}
Assuming you know the essentials of linear algebra, I don't think that the program will need much more explanation. I leave it as an exercise to you to figure out the pattern in the innermost loop and re-write it as two more nested loops. If your matrices are really just 2 × 2 then hard-coding the indices like this is probably the most readable way to write your program. As the matrices get bigger, you'd really want a loop.
The output of the C program is
373 396 437 464
693 736 757 804
1013 1076 1077 1144
1333 1416 1397 1484
which happens to be confirmed by the GNU Octave script.
For tiny matrices like this, performance is almost certainly a non-issue. If you are dealing with bigger matrices, you should be using a dedicated library such as (C)BLAS for your linear algebra computations. The BLAS interface has a somewhat steep learning curve and is not very convenient to use. If you have a chance to program in C++, there are much more expressive libraries such as Eigen that achieve comparable performance.
链接地址: http://www.djcxy.com/p/85988.html上一篇: 矩阵乘法的OpenMP性能问题
下一篇: 在C中将较大的矩阵乘以一个小矩阵