Help with matrix multiplication with a function, please!

This is a discussion on Help with matrix multiplication with a function, please! within the C Programming forums, part of the General Programming Boards category; First of all, sorry for the length of the code, I don't know how to copy and paste it without ...

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    3

    Help with matrix multiplication with a function, please!

    First of all, sorry for the length of the code, I don't know how to copy and paste it without all of the extra \n's. It's supposed to be a program that receives two matrices of maximum dimensions 10x10, adds the matrices (if possible), and multiplies the matrices (if possible). I have the addition working quite well, but the multiplication is being a pain. I've defined N as 10, and use N in my matrices as parameters, but the multiplication only works if the matrices are NxN, and not if they are 3x3 for example. Any help would be appreciated!
    Code:
    #include
    <stdio.h>
    
    #define
     N 10
    
    int
     main(void)
    
    {
    
    	
    /*	Declare variables.	*/
    
    	
    int i,j,NROWSA,NCOLSA,NROWSB,NCOLSB;
    
    	
    int mata[N][N],matb[N][N],matc[N][N],matd[N][N];
    
    	
    void matrixmult(int mata[N][N], int matb[N][N], int matc[N][N]);
    
    	
    void matrixadd(int mata[N][N], int matb[N][N], int matd[N][N]);
    
    
    	
    /*	Receive input from keyboard.	*/
    
    	printf(
    "Enter number of rows and number of columns for matrix A: \n");
    
    	scanf(
    "%i %i",&NROWSA,&NCOLSA);
    
    	
    
    	printf(
    "Enter matrix A row by row \n");
    
    	
    for (i=0; i<=NROWSA-1; i++)
    
    		
    for (j=0; j<=NCOLSA-1; j++)
    
    			scanf(
    "%i",&mata[i][j]);
    
    	
    for (i=0; i<=NROWSA-1; i++)
    
    	{
    
    		
    for (j=0; j<=NCOLSA-1; j++)
    
    			printf(
    "%i ",mata[i][j]);
    
    		printf(
    "\n");
    
    	}
    
    	
    
    	printf(
    "Enter number of rows and number of columns for matrix B: \n");
    
    	scanf(
    "%i %i",&NROWSB,&NCOLSB);
    
    	
    
    	printf(
    "Enter matrix B row by row \n");
    
    	
    for (i=0; i<=NROWSB-1; i++)
    
    		
    for (j=0; j<=NCOLSB-1; j++)
    
    			scanf(
    "%i",&matb[i][j]);
    
    	
    for (i=0; i<=NROWSB-1; i++)
    
    	{
    
    		
    for (j=0; j<=NCOLSB-1; j++)
    
    			printf(
    "%i ",matb[i][j]);
    
    		printf(
    "\n");
    
    	}
    
    	
    
    	matrixmult(mata,matb,matc);
    
    	
    if (NCOLSA != NROWSB)
    
    		printf(
    "Matrices cannot be multiplied. \n");
    
    	
    else
    
    	{
    
    		
    for (i=0; i<=NROWSA-1; i++)
    
    		{
    
    		
    for (j=0; j<=NCOLSB-1; j++)
    
    			printf(
    "%i ",matc[i][j]);
    
    		printf(
    "\n");
    
    		}
    
    	}
    
    
    	matrixadd(mata,matb,matd);
    
    	
    if (NROWSA != NROWSB || NCOLSA != NCOLSB)
    
    		printf(
    "These matrices cannot be added. \n");
    
    	
    else
    
    	{
    
    		
    for (i=0; i<=NROWSA-1; i++)
    
    		{
    
    			
    for (j=0; j<=NCOLSA-1; j++)
    
    				printf(
    "%i ",matd[i][j]);
    
    			printf(
    "\n");
    
    		}
    
    	}
    
    	
    return 0;
    
    }
    
    
    /*--------------------------function matrixmult------------------------*/
    
    /*	This function multiplies two compatible matrices. The dimensions   */
    
    /*	must be declared in the calling program as symbolic constants.	   */
    
    /*---------------------------------------------------------------------*/
    
    void
     matrixmult(int mata[N][N], int matb[N][N], int matc[N][N])
    
    {
    
    	
    /*	Declare variables.	*/
    
    	
    int i,j,k;
    
    
    	
    /*	Compute sums of products.	*/
    
    	
    for (i=0; i<=N-1; i++)
    
    		
    for (j=0; j<=N-1; j++)
    
    		{
    
    			matc[i][j] = 0;
    
    			
    for(k=0; k<=N-1; k++)
    
    				matc[i][j] += mata[i][k]*matb[k][j];
    
    		}
    
    		
    /*	Void return.	*/
    
    		
    return;
    
    }
    
    /*---------------------------function matrixadd------------------------*/
    
    /*	This function adds two compatible matrices. The dimensions must be */
    
    /*	declared in the calling program as symbolic constants.			   */
    
    /*---------------------------------------------------------------------*/
    
    void
     matrixadd(int mata[N][N], int matb[N][N], int matd[N][N])
    
    {
    
    	
    /*	Declare variables.	*/
    
    	
    int i,j;
    
    
    	
    /*	Compute sums of products.	*/
    
    	
    for (i=0; i<=N-1; i++)
    
    		
    for (j=0; j<=N-1; j++)
    
    			matd[i][j]=mata[i][j] + matb[i][j];
    
    
    	
    /*	Void return.	*/
    
    	
    return;
    
    }
    
    /*---------------------end of the function matrixadd-------------------*/
    

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I can't study your code really. Maybe use some different option settings in your editor?

    Can you just describe, in English, what it is that you are doing in your multiplication of the two matrices. Let's use the size that is giving your trouble - 3 x 3.

    Code:
    int a[3][3]={
       {1,2,4},
       {2,4,8},
       {3,6,9}
       };
    That should do for one matrix, how about you filling in the values you want to have tested, in matrix b?

    And describe how your code is doing the multiplication.

    We'll go from there.

  3. #3
    Registered User
    Join Date
    Oct 2011
    Posts
    23
    Your code is not pretty well formatted. Also, you may want to make your matrix a dynamic 2D array (static allocation is not very good when you deal with large numbers). Also, you may want to add a condition that checks if the number of rows from the first matrix is equal to the number of columns from the second matrix.
    Check this tutorials out:
    Dystopian Code: Defining a Numeric Matrix Structure in C
    Dystopian Code: The Sum and Product of Two Matrices in C

  4. #4
    Registered User
    Join Date
    Nov 2011
    Posts
    3
    Sorry about the format, when I copy and pasted it funked it up a bit. What I'm trying to do is create a program that uses the user-defined functions "matrixmult" and "matrixadd" (which are both near the bottom of the program and quite hard to read because of the format) to receive two matrices from the keyboard (with the user also defining the number of rows and columns for each of the two matrices) then multiply and add the two matrices together, if possible.

    dheaven: I do have a condition that checks that the number of columns of matrix A = the number of rows of matrix B, so that is not my problem. Also, our comp professor would like us to use the functions given in my program to multiply the two matrices, and we haven't learned enough for me to properly understand the code in your link.

    Adak: The user has to input the number of rows and columns for each matrix A and matrix B, so the solution has to be for any size of matrix up to 10x10.

    It would probably help a lot if I knew how to properly copy and paste the code to the forum haha, any tips?

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Check your editor options. I found changing the setting to "spaces only" and Windows/DOS text only, helped a lot.

    For a separate editor, I have used Notepad++ (it's free) and had good results with it. It will color your text for you if you tell it what language you're code is for. Windows notepad is marginal, and wants to add an extra newline at the end of each line from time to time. No idea why, but it's done it enough to me that I avoid it.

    Using an indentation between levels of subordination, of 3 char's width, has worked quite well. Personally, I really dislike this style of indentation:

    Code:
    for(i=0,j=2;i<MAX;i++)
            {
                 myArray[i] = i*j;
                 ++j;
            }
    Simply because it wastes so much horizontal real estate on my monitor, and it doesn't unite the braces with the first line of the loop, imo.

    The K&R style is my personal favorite:
    Code:
    for(i=0,j=2;i<MAX;i++) {
       myArray[i] = i*j;
       ++j;
    }
    
    
    //Another good one:
    for(i=0,j=2;i<MAX;i++) 
    {
        myArray[i] = i*j;
        ++j;
    }
    Use all lower case letters for local variables, Capitalize the first letter of any global variables, and make defines all CAPS. Try and keep your variables meaningfully named, but not 26 letters long. Don't use l (el) as a variable, because it looks to much like a 1 or a capital I (eye).

    Post up a compatible b array, and a plain text version of what your prof wants you to do to multiply the two matrices.

  6. #6
    Registered User
    Join Date
    Nov 2011
    Posts
    3
    I figured out what was wrong, I needed to define my NROWSA, NCOLSA, NROWSB, etc. in my function parameters, as integers, then refer to them again when I called my function in my program. Thanks anyways for the help guys!

    Adak: Thanks for the tips. For now I'll have to adhere to the format that our class uses, as our professor is pretty strict, but further on into my degree I'm sure I'll develop more stylistically in the way I program. I like your tips, thanks!

  7. #7
    Registered User
    Join Date
    Nov 2011
    Posts
    29
    Talking about matrix multiplication. If you want to speed up your algorithm, I've heard that by transposing the second matrix, so that you can multiply line by line instead of line by row, it will be I think around 50% more efficient (if I remember correctly) because the memory of the second matrix can be accessed linearly. Especially for large matrices this would be quite significant.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by naturegirl View Post
    Talking about matrix multiplication. If you want to speed up your algorithm, I've heard that by transposing the second matrix, so that you can multiply line by line instead of line by row, it will be I think around 50% more efficient (if I remember correctly) because the memory of the second matrix can be accessed linearly. Especially for large matrices this would be quite significant.
    Interesting. I'm confused by "line by line" compared to "line by row". I usually refer to a "line", as being the same thing as a "row". Can you clarify the difference or give an example or a url?

  9. #9
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,832
    Generally transposing a matrix is a very costly operation. If there are savings to be had later, they may be nullified by this overhead. Instead, what is recommended is to read the 2nd matrix in "virtual" column order. That is, initialize vectors of subtotals so that reading the A and B matrixes both processed in row-major order. Subtotals are summed into elements of this vector. This maximizes cache use of the system.
    Last edited by nonoob; 11-29-2011 at 01:10 PM.

  10. #10
    Registered User
    Join Date
    Nov 2011
    Posts
    29
    This time I can't write *rofl* Maybe it has to do with that I come here at the end of my day, and it's quite late here and English is not my first language
    I meant column instead of row

  11. #11
    Registered User
    Join Date
    Nov 2011
    Posts
    29
    @nonoob: what do you mean by subtotals? Is this a similar thing to what I was proposing? Basically that you change the reading of the columns to reading of rows in the second matrix? This would result in fewer cache misses since adjacent memory is being accessed?

  12. #12
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,832
    Yes, reading matrix 'B' row-wise. But to do that you'd set up a subtotal array of length equal to number of columns in array 'B'. Then traverse 'B' across the rows multiplying
    subtotal[1] += A[1;1] x B[1;1]
    subtotal[2] += A[1;1] x B[1;2]
    ...
    The idea is to access 'B' on contiguous memory locations. Likewise 'A'. Rather than jumping by length-of-row if you were to do columns.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 05-14-2011, 10:28 AM
  2. Problem in Matrix Multiplication (Using friend function)
    By wantsree in forum C++ Programming
    Replies: 3
    Last Post: 02-09-2011, 08:03 AM
  3. Matrix Multiplication again....
    By davidvoyage200 in forum C++ Programming
    Replies: 7
    Last Post: 11-21-2002, 05:35 PM
  4. matrix multiplication
    By fyodor in forum C Programming
    Replies: 2
    Last Post: 05-27-2002, 08:28 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21