Thread: Matrix Multiplication

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    1

    Matrix Multiplication

    I have so far written some code to multiply matrices together but I have come up against a few problems.

    Can someone please help me with the errors I have in my code:

    Code:
    #include<stdio.h>
    
    /* Allocate memory for a mtrix of given order */
    void  create_matrix( int ***mat, int m, int n)
    {
      int **la = NULL;
      int i;
    
      la = (int**)malloc( m* sizeof(int*));
    
      for ( i=0; i <m; i++ )
         la[i] = (int *)malloc( n* sizeof(int));
    
      *mat = la;
    
      return;
    }
    
    
    /* free  memory of matrix allocated in create_matrix() */
    
    void  free_matrix( int ***mat, int m)
    {
      int **la = NULL;
      int i;
    
      la = *mat;
    
      for ( i=0; i <m; i++ )
         free (la[i] );
    
      free ( la );
    
      *mat=NULL;
    
      return;
    }
    
    
    /* Print a matrix of order (mxn) */
    
    void  print_matrix( int **mat, int m, int n)
    {
      int i,j;
    
      printf("Matrix of order(%dx%d)\n",m,n);
      printf("\n");
      for ( i=0; i <m; i++ )
      {
        for ( j=0; j <n; j++ )
         printf("%4d",mat[i][j]);
        printf("\n");
      }
      return;
    }
    
    /* Read a matrix of order (mxn) */
    void  read_matrix( int **mat, int m, int n)
    {
      int i,j;
    
      printf("\nEnter %d elemnts for row, %d times\n",n,m);
    
      for ( i=0; i <m; i++ )
      {
        for ( j=0; j <n; j++ )
         scanf("%d",&mat[i][j]);
      }
      return;
    }
    int main()
    {
      int i,j,k;
      int **a,**b,**c;
    
      int m1,n1; /* A of m1xn1 */
      int m2,n2; /* B of m2xn2 */
    
      int m3,n3; /* C of m3xn3 => m1Xn2 (?) */
    
      while(1) {
    
        printf("\nEnter order of the First matrix: ");
        scanf("%d%d",&m1,&n1);
    
        printf("\nEnter order of the Second matrix: ");
        scanf("%d%d",&m2,&n2);
    
        /* Check if n1 == m2 */
        if ( m2 == n1 )
          break;
    
        printf("\nMatrices can not be multiplied.. Try again.. ");
        
      }
    
      m3 = m1;
      n3 = n2;
    
      /* Allocate memory for all three matrices */
    
      create_matrix( &a, m1, n1 );
      create_matrix( &b, m2, n2 );
      create_matrix( &c, m3, n3 );
    
      /* Read the matrices to be multiplied */
    
      read_matrix( a, m1, n1 );
      read_matrix( b, m2, n2 );
    
      print_matrix( a, m1, n1 );
      print_matrix( b, m2, n2 );
    
      /* Multyply the matrices */
    
      for ( i = 0; i < m3; i++ )
      {
        for ( j = 0; j < n3; j++ )
        {
           c[i][j] = 0;
    
           for ( k = 0; k < m2; k ++ )      
              c[i][j] += a[i][k]*b[k][j] ;
        }
      }
                
      print_matrix( c, m3, n3 );          
    
      free_matrix( &a, m1 );
      free_matrix( &b, m2 );
      free_matrix( &c, m3 );
    
     return 0;
    
    }

  2. #2
    Registered User
    Join Date
    Apr 2007
    Location
    Sweden
    Posts
    41
    Well, what errors are you experiencing?

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > la = (int**)malloc( m* sizeof(int*));
    A prime example of why malloc should not be cast (see the FAQ)

    The cast in this case is hiding the fact that you failed to include stdlib.h
    Try it without the cast, then include stdlib.h to see that the problem is fixed.

    Apart from that, the alloc/free side of things looks good. As for the actual multiply, compare your algorithm with say the one on www.mathworld.com.
    Or be more specific than "doesn't work".

    Oh, and since none of your code includes anything remotely like C++, I've moved it to the C board.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Apr 2007
    Location
    Sweden
    Posts
    41
    The reason I was asking what the problem was, was because it compiled and ran just fine with gcc under (Ubuntu) Linux. Shouldn't it?

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Maybe it does work OK.

    Maybe the OP should be more specific than "an error" or "some problems" like we all have exactly the same system therefore the answer must be obvious - NOT!
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Apr 2007
    Location
    Sweden
    Posts
    41
    I hear ya.

    (I also like it when they include an error message pointing to line 64 in a file and they post the whole 100+ line source without highlighting the line. Just because it is so much fun opening an editor and copy-and-paste the whole thing...)

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    141
    Perhaps this is just an academic exercise for you, but if you really want to do numeric matrix algebra in C there is really no replacement for using the BLAS libraries. A self tuning free library source can be found here
    http://math-atlas.sourceforge.net/

    The amd blas and lapack libraries are also free for download and might even work on intel cpus.
    http://developer.amd.com/acml.jsp

    It will need linux like tools if you are not on linux eg cygwin or maybe Msys and mingw. The libraries can then be converted to dll's which can be linked in Microsofts compilers.

    It will probably not be possible for you to come up with something better since there have been teams of phd.s working on this stuff for many years and some of the libraries have hand coded assembly.

    Even so, if you intend to write your own I would recommend using flattened array, where the row index runs the fastest. This is a 1-D array of size Mrows x Ncolumns. This is the Fortran array order and would give you better access to all the fortran numerical libraries, and it will give you a reasonably decent locality of reference for your memory accesses.
    Obviously the (m,n)'th entry would be at the n*Mrows + m offset into the array in this case. You could write a little macro to compute it for you.

    As it turns out the BLAS libraries will actually reorder your data into a format that leaves matrix subblocks neighbors to one another in memory, to minimize cache misses. The subblock size has to be tuned so that a matrix subblock fits in cache for your cpu.

    Finally I have no idea why you would perform matrix multiplication using integers!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C - access violation
    By uber in forum C Programming
    Replies: 2
    Last Post: 07-08-2009, 01:30 PM
  2. *operator overloading: scalar matrix multiplication
    By gemini_shooter in forum C++ Programming
    Replies: 4
    Last Post: 06-08-2009, 01:14 PM
  3. Matrix Multiplication ( Accessing data from a file ) HELP
    By six_degreez in forum C Programming
    Replies: 2
    Last Post: 07-24-2008, 05:21 PM
  4. Matrix Help
    By HelpmeMark in forum C++ Programming
    Replies: 27
    Last Post: 03-06-2008, 05:57 PM