Thread: matrix mult - double ptr in col major

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    17

    matrix mult - double ptr in col major

    Hey,

    I'm creating a matrix-matrix multiplier in C that will use the same format as the GOTO BLAS and ATLAS implementations. I need to allocate memory and store the matrices in COL MAJOR format not in row major as is the standard C representation.

    Can you tell me if I am on the right track here:
    Code:
    //global vars
    double **matrixA, **matrixB, **matrixC;
    
    int main(int argc, char *argv[])
    {
    	int i, c, row, col, j;
    	int n_rows = 10; //ASSUME SQUARE FOR NOW!
    	int m_cols =  10;
    	int mbyn = m_cols * n_rows;
            int i, j;
            double n = 0;
    
    //allocate the number of cols
    matrixA = (double**)malloc( sizeof( double* ) * m_cols); 
    
    //allocate the overall size??
    matrixA[0] = (double *) malloc( sizeof( double*) * mbyn);
    	
    for (i=1; i<m_cols; i++)	
    {       //for each col allocate the rows
    	matrixA[i] = *matrixA + i * n_rows; 
    }
    I then have a function fill matrix so:

    Code:
      for (i=0; i<SIZE; i++) //
        for (j=0; j<SIZE; j++)
          matrix[j][i] = n++;  //or a[i][j];  //fill it col,row - like a graphics point

    I think the malloc is correct but i'm not so sure about the filling of the matrix. Is this right??

    I want it to work like this:
    Image Attachment
    (sorry don't know how to display the image in here.)

    So that I have one long linear array, that stores one row, then the next row etc. This means that I can skip to the next element one by one the whole way throught the matrix. To get to the next row of a matrix with n cols I would simply move n elements from the start pointer.

    thanks for your help,

    Colm Mitchell

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >So that I have one long linear array, that stores one row, then the next row etc.

    The only way to do that is just have a single pointer, and access column and row using pointer arithmetic.

    Instead of:
    double **matrixA, **matrixB, **matrixC;

    You would have:
    double *matrixA, *matrixB, *matrixC;

  3. #3
    Registered User mrafcho001's Avatar
    Join Date
    Jan 2005
    Posts
    483
    i am not sure what you are trying to do but you can use mutli-dimentional arrays to store whole tables.

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Second example here.

    I know this came up here recently and Salem had a really nice solution... this thread: here.

    [edit=3]I'm not sure if this is quite what you're after.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int **foo(int nrows, int ncolumns)
    {
       int i, **array2 = malloc(nrows * sizeof *array2);
       if ( array2 )
       {
          array2[0] = malloc(nrows * ncolumns * sizeof *array2[0]);
          if ( array2[0] )
          {
             for ( i = 1; i < nrows; i++ )
             {
                array2[i] = array2[0] + i * ncolumns;
             }
          }
       }
       return array2;
    }
    
    void bar(int **array)
    {
       free(array[0]);
       free(array);
    }
    
    int main(void)
    {
       int r, c, i = 0, rows = 3, cols = 5, **myarray = foo(cols, rows);
       for ( c = 0; c < cols; ++c )
       {
          for ( r = 0; r < rows; ++r )
          {
             myarray[c][r] = i++;
             printf("%p : myarray[%d][%d] = %d\n",
                    (void*)&myarray[c][r], c, r, myarray[c][r]);
          }
       }
       bar(myarray);
       return 0;
    }
    
    /* my output
    007A3208 : myarray[0][0] = 0
    007A320C : myarray[0][1] = 1
    007A3210 : myarray[0][2] = 2
    007A3214 : myarray[1][0] = 3
    007A3218 : myarray[1][1] = 4
    007A321C : myarray[1][2] = 5
    007A3220 : myarray[2][0] = 6
    007A3224 : myarray[2][1] = 7
    007A3228 : myarray[2][2] = 8
    007A322C : myarray[3][0] = 9
    007A3230 : myarray[3][1] = 10
    007A3234 : myarray[3][2] = 11
    007A3238 : myarray[4][0] = 12
    007A323C : myarray[4][1] = 13
    007A3240 : myarray[4][2] = 14
    */
    Last edited by Dave_Sinkula; 03-21-2005 at 03:36 PM. Reason: [1] Found thread. [2] Isolated post. [3] Added code.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    After reading Dave's link, ignore my post.

  6. #6
    Registered User
    Join Date
    Mar 2005
    Posts
    17
    Ok - i got a bit confused by that so had to ask my supervisor again...

    Swoopy you were on the right track - I need to have a single pointer instead of a double so
    You would have:
    double *matrixA, *matrixB, *matrixC;
    would work.

    This means that when i go to fill the matrix for example i need to do it not like
    PHP Code:
    matrix[1][2] = X
    but as
    PHP Code:
    matrix[0]+ X
    where Y is the Yth element of that row. Meaning that I start a particular column and then move along the array to find the element in the Yth row of that col.

    Dave in what way will I need to change the memory allocation because of this?

    Thanks for your help guys!

    Colly.

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by collymitch
    Dave in what way will I need to change the memory allocation because of this?
    Then look at the third example there...
    Quote Originally Posted by Dave_Sinkula
    Second example here.
    To do it column major, you'd do the indexing differently. Maybe something like this.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
       size_t rows = 3, cols = 5;
       double *myarray = malloc(rows * cols * sizeof *myarray);
       if ( myarray )
       {
          size_t r, c;
          for ( r = 0; r < rows; ++r )
          {
             for ( c = 0; c < cols; ++c )
             {
                size_t i = c * rows + r;
                myarray[i] = (r + 1) + (c + 1) / 10.0;
                printf("{%d,%d} %p : myarray[%2d] = %g\n", (int)r, (int)c,
                       (void*)&myarray[i], (int)i, myarray[i]);
             }
          }
          free(myarray);
       }
       return 0;
    }
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

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. Compiling c++ intrinsics commands
    By h3ro in forum C++ Programming
    Replies: 37
    Last Post: 07-13-2008, 05:04 AM
  3. Copying 2-d arrays
    By Holtzy in forum C++ Programming
    Replies: 11
    Last Post: 03-14-2008, 03:44 PM
  4. Conversion From C++ To C
    By dicon in forum C++ Programming
    Replies: 2
    Last Post: 06-10-2007, 02:54 PM
  5. Hi, could someone help me with arrays?
    By goodn in forum C Programming
    Replies: 20
    Last Post: 10-18-2001, 09:48 AM