将一个小矩阵乘以C中较大的矩阵

时间:2015-02-25 04:14:49

标签: c matrix

我有一个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];   
  }
}

1 个答案:

答案 0 :(得分:0)

如果您编写的是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的大部分兼容free software替代品 - 它会产生以下输出:

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%8d\n", 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,可以达到相当的性能。