【问题标题】:Matrix Multiplication using divide&conquer矩阵乘法使用分治法
【发布时间】:2019-03-13 18:28:43
【问题描述】:

我正在编写代码以使用分治法执行矩阵乘法。我的代码是这样的:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define SIZE 8  //Able to change size

void add(int **a, int **b, int size, int **c)
{
    int i, j;
    for(i=0; i<size; i++)
    {
        for(j=0; j<size; j++)
        {
            c[i][j]=a[i][j]+b[i][j];
        }
    }
}

void subtract(int **a, int **b, int size, int **c)
{
    int i, j;
    for(i=0; i<size; i++)
    {
        for(j=0; j<size; j++)
        {
            c[i][j]=a[i][j]-b[i][j];
        }
    }
}

void multiply(int **c, int **d, int size, int **result)
{
    if(size==1)
    {
        result[0][0]=c[0][0]*d[0][0]; /*Could this base case calculation be wrong?*/
    }
    else
    {
        int i, j;
        int new_size=size/2;

        int **c11=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            c11[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **c12=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            c12[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **c21=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            c21[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **c22=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            c22[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **d11=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            d11[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **d12=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            d12[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **d21=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            d21[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **d22=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            d22[i]=(int *)malloc(new_size*sizeof(int));
        }

        int **temp1=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            temp1[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **temp2=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            temp2[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **temp3=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            temp3[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **temp4=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            temp4[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **temp5=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            temp4[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **temp6=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            temp6[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **temp7=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            temp7[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **temp8=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            temp8[i]=(int *)malloc(new_size*sizeof(int));
        }

        int **res1=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            res1[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **res2=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            res2[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **res3=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            res3[i]=(int *)malloc(new_size*sizeof(int));
        }
        int **res4=(int **)malloc(new_size*sizeof(int *));
        for(i=0; i<new_size; i++)
        {
            res4[i]=(int *)malloc(new_size*sizeof(int));
        }

        for(i=0; i<new_size; i++)
        {
            for(j=0; j<new_size; j++)
            {
                c11[i][j]=c[i][j];
                c12[i][j]=c[i][j+new_size];
                c21[i][j]=c[i+new_size][j];
                c22[i][j]=c[i+new_size][j+new_size];
                d11[i][j]=d[i][j];
                d12[i][j]=d[i][j+new_size];
                d21[i][j]=d[i+new_size][j];
                d22[i][j]=d[i+new_size][j+new_size];
            }
        }

        multiply(c11, d11, new_size, temp1);
        multiply(c12, d21, new_size, temp2);
        multiply(c11, d12, new_size, temp3);
        multiply(c12, d22, new_size, temp4);
        multiply(c21, d11, new_size, temp5);
        multiply(c22, d21, new_size, temp6);
        multiply(c21, d12, new_size, temp7);
        multiply(c22, d22, new_size, temp8);
        add(temp1, temp2, new_size, res1);
        add(temp3, temp4, new_size, res2);
        add(temp5, temp6, new_size, res3);
        add(temp7, temp8, new_size, res4);

        int x=0;
        int y=0;
        int z=0;
        int w=0;
        for(i=0; i<2*new_size; i++)
        {
            for(j=0; j<2*new_size; j++)
            {
                if(i<new_size && j<new_size)
                {
                    result[i][j]=res1[i][j];
                }
                if(i<new_size && j>=new_size)
                {
                    x=j-new_size;
                    result[i][j]=res2[i][x];
                }
                if(i>=new_size && j<new_size)
                {
                    y=i-new_size;
                    result[i][j]=res3[y][j];
                }
                if(i>=new_size && j>=new_size)
                {
                    z=i-new_size;
                    w=j-new_size;
                    result[i][j]=res4[z][w];
                }
            }
        }
    free(c11);
    free(c12);
    free(c21);
    free(c22);
    free(d11);
    free(d12);  
    free(d21);  
    free(d22);
    free(temp1);
    free(temp2);
    free(temp3);
    free(temp4);
    free(temp5);
    free(temp6);
    free(temp7);
    free(temp8);
    free(res1);
    free(res2);
    free(res3);
    free(res4);
    }
}

int main(void)
{   
    int i, j;

    int **A=(int **)malloc(SIZE*sizeof(int *));
    for(i=0; i<SIZE; i++)
    {
        A[i]=(int *)malloc(SIZE*sizeof(int));
    }
    int **B=(int **)malloc(SIZE*sizeof(int *));
    for(i=0; i<SIZE; i++)
    {
        B[i]=(int *)malloc(SIZE*sizeof(int));
    }
    int **C=(int **)malloc(SIZE*sizeof(int *));
    for(i=0; i<SIZE; i++)
    {
        C[i]=(int *)malloc(SIZE*sizeof(int));
    }

    int count=0;
    int sum=0;
    srand(time(NULL));
    for(i=0; i<SIZE; i++)
    {
        for(j=0; j<SIZE; j++)
        {
            A[i][j]=rand()%1000;
        }
    }

    for(i=0; i<SIZE; i++)
    {
        for(j=0; j<SIZE; j++)
        {
            B[i][j]=rand()%1000;
        }
    }

    for(i=0; i<SIZE; i++)
    {
        for(j=0; j<SIZE; j++)
        {
            C[i][j]=0;
        }
    }

    for(i=0; i<SIZE; i++)
    {
        for(j=0; j<SIZE; j++)
        {
            printf("%5d", A[i][j]);
        }
        printf("\n");
    }

    printf("\n");

    for(i=0; i<SIZE; i++)
    {
        for(j=0; j<SIZE; j++)
        {
            printf("%5d", B[i][j]);
        }
        printf("\n");
    }
    multiply(A, B, SIZE, C);

    for(i=0; i<SIZE; i++)
    {
        for(j=0; j<SIZE; j++)
        {
            printf("%5d", C[i][j]);
        }
        printf("\n");
    }
    free(A);
    free(B);
    free(C);

}

该代码旨在生成随机的两个 n*n 矩阵,将大矩阵分成两半,并递归地乘以子矩阵,正如您可能知道的那样。计算后,我显示乘法的结果。我将计算出的子矩阵放入结果矩阵中。

我尝试过使用调试器,但程序会在片刻后退出。根据我以前的经验,我怀疑变量的初始化可能存在一些问题,但目前对我来说似乎很好。

谁能指出我错过了什么?很抱歉中间有多余的 malloc。在我发现代码正常工作后,我将创建一个函数。非常感谢您。

【问题讨论】:

  • 我通过在启用调试和禁用优化的情况下编译并在调试器中运行来诊断这一点。调试器在例程multiply 中的语句result[0][0]=c[0][0]*d[0][0] 上显示错误。在调试器中,我打印了c、c[0]、d、d[0]、result 和result[0] 以查看哪个有问题。这表明result[0] 为零。然后我查找对multiply 的每个调用,并插入一个printf 语句来打印x[0],其中x 是传递给multiply 的result 参数。这表明 temp5 尚未设置。

标签: c malloc matrix-multiplication


【解决方案1】:

您的代码包含:

    int **temp5=(int **)malloc(new_size*sizeof(int *));
    for(i=0; i<new_size; i++)
    {
        temp4[i]=(int *)malloc(new_size*sizeof(int));
    }

temp4 是一个错字; temp5[i] 的内容永远不会被设置。

【讨论】:

    猜你喜欢
    • 2011-06-18
    • 2016-05-01
    • 2017-12-05
    • 2020-06-12
    • 2020-04-11
    • 2012-03-04
    • 2017-07-16
    • 1970-01-01
    • 2016-11-17
    相关资源
    最近更新 更多