使用指针的矩阵乘法中的错误

时间:2013-12-14 13:13:58

标签: c matrix

我正在尝试按照here给出矩阵乘法优化:

for(i=0;i<n;i++)
{
    for(k=0;k<n;k++)
    {
        for(j=0;j<n;j++)
            C[i][j]+=A[i][k]*B[k][j];
     }
}

我正在尝试使用矩阵指针而不是静态数组来实现上述功能:

int *A,*B,*C;

   A= (int*)malloc(sizeof(int*)*(n * n));
   B= (int*)malloc(sizeof(int*)*(n * n));
   C= (int*)malloc(sizeof(int*)*(n * n));

    for ( i = 0 ; i < n ; i++ )
    {
      for ( k = 0 ; k < n ; k++ )
      {  sum=0;
        for ( j = 0 ;  j< n ; j++ )
        {
           double c =A[i*n + k];                              
           double d =B[k*n + j];
           sum+=c*d;                             
    }
      C[i*n + j] =sum;
      }


    }

但答案与上面的代码片段不一样  我在Linux ubuntu 12.04中运行此代码。请帮忙解决这个问题。是否有任何逻辑错误?

更新

考虑以下示例:

matrix A

1  1

1  1



matrix B

1   1

1   1

和预期的输出矩阵

  matrix C 

  2    2 

  2    2

但是对于使用如上所示的指针进行矩阵乘法优化,输出是不同的

   matrix C

   0    0 

   7    9

2 个答案:

答案 0 :(得分:2)

sum=0;
for ( j = 0 ;  j< n ; j++ )
{
    double c =A[i*n + k];
    double d =B[k*n + j];
    sum+=c*d;
}
C[i*n + j] =sum;

你的代码有两个问题。

  1. 加上总和是错误的。 (逻辑错误)
  2. i*n + j当j循环时,总是n(2)。
  3. 应该是

    for ( i = 0 ; i < n ; i++ ){
        for ( k = 0 ; k < n ; k++ ){
            for ( j = 0 ;  j< n ; j++ ){
                C[i*n + j] +=A[i*n + k]*B[k*n + j];//C initialized by 0
            }
        }
    }
    

    也应该是

    A= (int*)malloc(sizeof(int)*(n * n));//not sizeof(int*)
    B= (int*)malloc(sizeof(int)*(n * n));
    C= (int*)calloc(n*n, sizeof(int));
    

答案 1 :(得分:0)

矩阵可以被认为是一个2D数组,这样你就可以使用数组寻址,这有助于阅读代码

我会像这样实现动态数组乘法。

这可能是你想要做的一个可能的实现,它将2个矩阵相乘并动态存储结果,我假设你有一些方法可以通过命令行将矩阵输入到程序中

#include<stdio.h>
//this function returns a pointer to the new array. 
int **makeMatrix(int,int);

int **makeMatrix(ROWS,COLS){
int i=0;
//your code u use sizeof(*int) this is wrong suppose you use a 64bit machine 
//then sizeof(*int) is going to be 8bytes(64bits)!, whereas an integer can be 32bits, 
//the size of the integer is completely compiler dependent, does not matter if you 
//have 64bit hardware.


int **array1 = malloc(sizeof(int *)*ROWS);
for(i=0;i<Columns;i++)
array1[i] = malloc(sizeof(int)*COlUMNS);
return array1;
//we are making a 2D array here so we can use array notation to address the memory
//A[row][column] is the same as *(*(A + row) + column), this makes the code neat unlike
//your method which is also very correct but i prefer the old array notation.
}

int main(void){

int set_row1,set_row2,set_row3,set_column1,set_column2,set_column3;
int row1,column1,column;

int **array1 = makeMatrix(set_row1,set_column1);
int **array2 = makeMatrix(set_row2,set_column2);
int **result = makeMatrix(set_row3,set_column3);
//now we have 3 matrices that we can use//i assume you initialise them somehow 
 //with numbers

//now the multiplication part.we can use normal array notation since we are 
// using   essentialy a 2D array, your method is also corret where you allocate the 
// entire array on a boxed piece of memory.  

//also need to check if the 2 matrix can be multiplied.
 int temp =0;
if(Column1 == Row2) //they can be multiplied together
{

for(row1=0;row1<set_row1;row1++){
   for(column2=0;column2<set_column2;column2++){
       for(column1=0;column1<set_column1;column1++){
        temp += array1[row1][column1]*array2[column1][column2]
        }
   result[row1][column2] = temp;
   }
}
else
//do something

!还没有编译这个期待一些警告等:)