在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

上一篇: Multiplying a small matrix inside a bigger matrix in C

下一篇: Multiplying matrix columns