Thread: Matrix multipliers - using a double pointer instead of an array

  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    17

    Question Matrix multipliers - using a double pointer instead of an array

    Hey,
    I'm working on an openMP enabled matrix-matrix multiplier that will multiply two matrices, A and B, storing the result in C. I have been told to write it in C, of which I have no experience. Before I even begine to think about the omp options I have a few problems to overcome (actually I have many but these are my worst.)

    Prob 1:
    I need to use a double pointer to store the matrices instead of the following array based approach. (This is because I will not know what the matrix sizes will be at compile time.)

    Code:
    double A[SIZE][SIZE], B[SIZE][SIZE], C[SIZE][SIZE];
    am I on the right track by using:

    Code:
    double *a, *b, *c;
    I believe this creates 3 pointers to doubles, but are they only single dimensions?? Do they need to be declared as> double **a ...?

    Prob 2:
    By using a double pointer I think I will need to use the malloc function to allocate the memory required.

    Code:
    a = (double *)malloc(sizeof(double)*m*n);
    where m and n are the matrix dimensions. Is this correct?

    I appreciate the help and I am sorry if this has been done before but I couldn't find it.

    Thanks,

    Colly Mitchell

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You should do a board search for dynamic arrays, or multidimension arrays. Few things:

    1) Yes, you'll need a pointer to a pointer to a type:
    Code:
    double **matrix;
    2) Yes, you'll need to use malloc, but you don't typecast the return of it.
    3) You allocate N pointers first.
    Code:
    matrix = malloc( sizeof( double * ) * N );
    4) Using a loop, for each N pointer allocated, allocate M doubles.
    Code:
    matrix[ x ] = malloc( sizeof( double ) * M );
    5) You need to free in the reverse order. (Step 4, freeing, step 3 freeing.)

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Mar 2005
    Posts
    17
    Hey thanks,

    Ok that helped a bit. I read that an array name is just a pointer to the beginning of the allocated memory space. Does this mean I treat the matrix just as an array?

    I know that If i want to access the 2nd row element of the 3rd col in an array I would use
    Code:
     matrixArray[1][2]
    but what do i use for a pointer then? is it just the same
    Code:
    pointerArray[1][2]
    If I want to call a funt to fill the matrix can i use:
    Code:
    void fill_matrix(double **matrix)
    {
      int i, j, n = 0;
      for (i=0; i<SIZE; i++)
          for (j=0; j<SIZE; j++)
             matrix[i][j] = n++;
    }
    Do I allocate the memory when I create the matrix or when I am ready to fill it? Will this work?

    Code:
    double **matrixA, **matrixB, **matrixC;
    
    void main(...)
    {
    ...
       m = num_rows;
       n = num_cols;
    
       matrixA = malloc(sizeof(double)*m*n);
       matrixB = malloc(sizeof(double)*n);
       matrixC = malloc(sizeof(double)*n);
    
       fill_matrix(matrixA);
    ...
    }
    I apologise if i've messed it up.

    Thanks,

    Colly

  4. #4
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Quote Originally Posted by collymitch
    Code:
    void main(...)
    GASP!
    http://faq.cprogramming.com/cgi-bin/...&id=1043284376
    Woop?

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    No. Read what I wrote. You have to allocate a bunch of pointers to doubles. Each of those pointers represents a row. Then, for each row, you allocate a bunch of doubles. These represent the data in the columns of that row. And yes, you can index it like an array.

    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You can also just allocate one large 1D array and access it in 2D. This will come down to using offsets into the array instead of actual 2D arrays - which by the way are only 2D compiler side. In assembly, it's just one huge linear array and by using 2D arrays you are forcing your compiler to re-compute the offset every time you access the array.

    If you are not worried about efficiency then have at it, but I stay away from 2D arrays and try to stay away from the multiple indirection that is associated with them. It tends to get rather confusing.

  7. #7
    Registered User
    Join Date
    Mar 2005
    Posts
    17

    Question

    Ok....

    Yeah the 'void main' bit was a typing mistake - i had called the function something else but changed it to main but forgot to change the rest. I was just trying to show a quick example. Sorry.

    So is malloc just like using NEW in java or vb where it does malloc automatically?

    I sort of get it but what does the
    Code:
    matrix[x] =...
    mean?

    Using a loop, for each N pointer allocated, allocate M doubles.
    Does this leave me with a nested loop then like so:

    Code:
    double **matrixA;
    say matrixA has m rows and n cols

    Code:
    	
    for (i=0; i<m_rows; i++)
    		//each pointer to double represents each row
                     matrixA = malloc( sizeof( double * ) * m_rows ); 
                    		
                    for (j=0; j<n_cols; j++)
    
    			// for each row allocate doubles for the cols
    			matrixA[i][j] = malloc( sizeof( double ) * n_cols );
    This doesn't work as it won't assign the void * type to the double type of the matrixA. So what does the matrix[x] in
    Code:
    matrix[ x ] = malloc( sizeof( double ) * M );
    mean again??

    Thanks for the help, I feel that i'm starting to get somewhere now.

    Colm

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Here ya go:
    Code:
    /* Create a soon-to-be matrix of doubles, named dmatrix */
    double **dmatrix;
    int row;
    
    /* Now we need to allocate N 'rows'. */
    dmatrix = malloc( sizeof( double* ) * N );
    
    /* Now, for each row, allocate M actual doubles. */
    for( row = 0; row < N; row++ )
        dmatrix[ row ] = malloc( sizeof( double ) * M );
    
    /* Now you have a matrix of N rows by M colums worth of doubles. */
    You can now use this as a 2D array in effect.
    Code:
    dmatrix[ foo ][ bar ] = 2.3;
    To free what you've allocated, you do those two steps in reverse. You free each row's doubles, then you free the pointers (ie: rows)
    Code:
    for( row = 0; row < N; row++ )
        free( dmatrix[ row ] ); /* Free this row's doubles. */
    free( dmatrix ); /* Free the row holders. */
    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    Mar 2005
    Posts
    17
    Hey I've got that set up and working fine now by the way. It was a great help it got my program kicked off and have made a good deal of progress so thanks for your help quzah!

    Colm.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ to C Conversion
    By dicon in forum C Programming
    Replies: 7
    Last Post: 06-11-2007, 08:38 PM
  2. Conversion From C++ To C
    By dicon in forum C++ Programming
    Replies: 2
    Last Post: 06-10-2007, 02:54 PM
  3. newbie needs help with code
    By compudude86 in forum C Programming
    Replies: 6
    Last Post: 07-23-2006, 08:54 PM
  4. Unknown Math Issues.
    By Sir Andus in forum C++ Programming
    Replies: 1
    Last Post: 03-06-2006, 06:54 PM
  5. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM