【问题标题】:How do I multiply a matrix by a matrix in C? Why doesn't this work?如何将矩阵乘以C中的矩阵?为什么这不起作用?
【发布时间】:2014-11-01 03:39:12
【问题描述】:

这是我正在开发的程序。任务是乘以 2 个矩阵。矩阵 A 中的列数与矩阵 B 中的行数相同。下面是对两个矩阵包含的内容以及预期结果的评论。计算结果就是我的程序所做的。

void matrixMul(Matrix A, Matrix B, int ARows, int ACols, int BCols, Matrix C){
int k;
int l;
int j;
    for(j=0; j < ARows; j++) {
        for (l=0; l < BCols; l++) {
            for (k=0; k < ACols; k++) {
                C[j][l] += A[j][k] * B[k][l];
            }/*for*/
        }/*for*/
    }/*for*/
}/*matrixMul*/


/*This is what the output should be....
  ==> Computing 0.0   1.0   2.0      0.0   1.0   2.0
                1.0   2.0   3.0  *   3.0   4.0   5.0
                2.0   3.0   4.0      6.0   7.0   8.0

==> Expected    15.0  18.0  21.0
                24.0  30.0  36.0
                33.0  42.0  51.0

==> Computed    15.0  20.0  25.0
                28.0  36.0  44.0
                41.0  52.0  63.0 */

【问题讨论】:

  • 欢迎来到 Stack Overflow。请尽快阅读About 页面。 Matrix 是什么类型?你能显示打印出你的两个矩阵的代码吗?在开始添加之前,您是否将矩阵 C 设置为零?请查看如何创建 MCVE (How to create a Minimal, Complete, and Verifiable Example?) 或 SSCCE (Short, Self-Contained, Correct Example) — 相同基本思想的两个名称和链接。
  • 在中间循环中,您是否尝试在最里面的循环开始之前添加c[l][k] = 0。那会发生什么?此外,您似乎在矩阵内玩整数以外的东西,也请详细说明这一点。
  • @nIcEcOw:我认为在第三个嵌套循环之前添加C[j][l] = 0; 是对的。

标签: c arrays matrix multiplication


【解决方案1】:

您的方程式看起来正确。我只能猜测C 在计算之前没有初始化为全零。我会这样做(只是为了确定):

for(j=0; j < ARows; j++) {
    for (l=0; l < BCols; l++) {
        C[j][l] = 0;                      // <- Init C to zero
        for (k=0; k < ACols; k++) {
            C[j][l] += A[j][k] * B[k][l];
        }
    }
}

【讨论】:

    【解决方案2】:

    当矩阵 C 归零时,您的代码可以正常工作:

    #include <stdio.h>
    
    typedef double Matrix[3][3];
    
    static void print_matrix(const char *tag, Matrix M);
    static void matrixMul(Matrix A, Matrix B, int ARows, int ACols, int BCols, Matrix C);
    
    void matrixMul(Matrix A, Matrix B, int ARows, int ACols, int BCols, Matrix C)
    {
        int k;
        int l;
        int j;
        for (j = 0; j < ARows; j++)
        {
            for (l = 0; l < BCols; l++)
            {
                for (k = 0; k < ACols; k++)
                {
                    C[j][l] += A[j][k] * B[k][l];
                }
            }
        }
    }
    
    int main(void)
    {
        Matrix A = { { 0.0, 1.0, 2.0 }, { 1.0, 2.0, 3.0 }, { 2.0, 3.0, 4.0 }, };
        Matrix B = { { 0.0, 1.0, 2.0 }, { 3.0, 4.0, 5.0 }, { 6.0, 7.0, 8.0 }, };
        Matrix C = { { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 }, };
    
        print_matrix("A", A);
        print_matrix("B", B);
    
        matrixMul(A, B, 3, 3, 3, C);
    
        print_matrix("C", C);
        return 0;
    }
    
    static void print_matrix(const char *tag, Matrix M)
    {
        printf("%s:\n", tag);
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
                printf("%6.2f", M[i][j]);
            putchar('\n');
        }
    }
    

    输出:

    A:
      0.00  1.00  2.00
      1.00  2.00  3.00
      2.00  3.00  4.00
    B:
      0.00  1.00  2.00
      3.00  4.00  5.00
      6.00  7.00  8.00
    C:
     15.00 18.00 21.00
     24.00 30.00 36.00
     33.00 42.00 51.00
    

    您可以轻松地修复乘法函数中的代码,以便结果矩阵的初始内容无关紧要:

    void matrixMul(Matrix A, Matrix B, int ARows, int ACols, int BCols, Matrix C)
    {
        for (int j = 0; j < ARows; j++)
        {
            for (int l = 0; l < BCols; l++)
            {
                int sum = 0;
                for (int k = 0; k < ACols; k++)
                    sum += A[j][k] * B[k][l];
                C[j][l] = sum;
            }
        }
    }
    

    一个好的优化编译器很有可能会生成与此修订版中基本相同的代码,但C[j][l] 不在最内层循环中使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-20
      相关资源
      最近更新 更多