Thread: Matrix Multiplication

  1. #1
    Registered User
    Join Date
    May 2010
    Location
    Isla Vista
    Posts
    34

    Matrix Multiplication

    I have some code here to multiply matrices. It's not working as designed. Any suggestions? I want it to multiply a matrix then continue to do so until it reaches n. So, the desire output is A^n, with input n.
    Code:
    #include <stdio.h>
    #include <math.h>
    
    void multmtrx(int A[2][2], int B[2][2], int result[2][2])
    {
    	for (int i=0; i<2; i++){
    		for (int j=0; j<2; j++)
    		for (int k=0; k<2; k++)
    			result[i][j]=A[i][k]*B[k][j];}
    }
    
    void printmtrx(int result[2][2])
    {
    	printf("\nThis is your new matrix.\n");
    	for (int i=0; i<2; i++)
    	{	for (int j=0; j<2; j++)
    		printf(" %d", result[i][j]);
    		printf("\n");
    	}
    }
    void main()
    {
    	int sigma_x[2][2]={{0,1},{1,0}};
    	/* Imaginary numbers needed */
    	/* int sigma_y[2][2]={{0,0},{0,0}}; */
    	int sigma_z[2][2]={{1,0},{0,-1}};
    	int result[2][2]={{0,0},{0,0}};
    	int n;
    	printf("\nHow many times do you want to multiply the matrix?");
    	scanf("%dd", &n);
    	printf("\nThe matrix will be multiplied %d times.", n);
    	for (int i=2; i<=n; i++){
    	multmtrx(sigma_x, sigma_z, result);
    	printmtrx(result);}
    	
    	printf("\nAgain?");
    	scanf("%dd", &n);
    	if (n==1) main();
    }

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    First of all void main = bad. The correct way is either int main(void) or int main(int argc, char *argv[]) if you need command line arguments.

    Secondly you haven't figured out the algorithm to multiply matrices. This is not a C problem, it's a math problem.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  3. #3
    Registered User
    Join Date
    May 2010
    Location
    Isla Vista
    Posts
    34
    Quote Originally Posted by claudiu View Post
    First of all void main = bad. The correct way is either int main(void) or int main(int argc, char *argv[]) if you need command line arguments.

    Secondly you haven't figured out the algorithm to multiply matrices. This is not a C problem, it's a math problem.
    Sorry, this code isn't right. I've done some editing and this is now the correct code.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    void multmtrx(int A[2][2], int *B, int *result)
    {
    	for (int i=0; i<2; i++){
    		for (int j=0; j<2; j++)
    		for (int k=0; k<2; k++)
    			result[2*i+j]+=A[i][k]*B[2*k+j];}
    }
    
    void printmtrx(int *result)
    {
    	printf("\nThis is your new matrix.\n");
    	for (int i=0; i<2; i++)
    	{	for (int j=0; j<2; j++)
    		printf(" %d", result[2*i+j]);
    		printf("\n");
    	}
    }
    void main()
    {
    	int sigma_x[2][2]={{0,1},{1,0}};
    	int sigma_z[2][2]={{1,0},{0,-1}};
    	int ID[2][2]={{1,0},{0,1}};
    	int n;
    	int *temp;
    	
    	temp = (int*)malloc(sizeof(int) * 4);
    	temp[0] = 0;
    	temp[1] = 1;
    	temp[2] = 1;
    	temp[3] = 0;
    	
    	int *result;
    	
    	do {
    	
    		printf("\nHow many times do you want to multiply the matrix?\n");
    		printf("This returns A^n\n");
    		scanf("%d", &n);
    		printf("\nThe matrix will be multiplied %d times.", n);
    
    		for (int i = 1; i < n; i++) {
    		result = (int*)malloc(sizeof(int) * 4);
    		result[0] = 0;
    		result[1] = 0;
    		result[2] = 0;
    		result[3] = 0;
    
    		multmtrx(sigma_x, temp, result);
    		int *tempPointer;
    		tempPointer = result;
    		free(temp);
    		temp = tempPointer;
    		}
    	
    		printmtrx(temp);
    		printf("\nAgain?");
    		scanf("%d", &n);
    		} 
    	while (n==1);
    }
    So, after 1 run, it definately does A^n, but if you continue running it, then the values are incorrect. How can I free the variable and restart the operation?

  4. #4
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Perhaps you haven't heard me the first time: void main = bad.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Are you intending to restart the count over again, or continue on from where you left off? If the first, you need to reset temp to its original value inside the do-while loop. If the latter, you need to make sure the right number of multiplications happen.

  6. #6
    Registered User
    Join Date
    May 2010
    Location
    Isla Vista
    Posts
    34
    I am actually trying to reset the counter. So it does the multmtrx op again from scratch. I tried to move it to a func.
    Code:
    void expon(int A[2][2], int m)
    {
    	int *temp;
    	
    	temp = (int*)malloc(sizeof(int) * 4);
    	for (int i=0; i<2; i++)
    		for (int j=0; j<2; j++)
    			temp[i]=A[i][j];
    	int *result;
    	for (int i = 1; i < m; i++) {
    		result = (int*)malloc(sizeof(int) * 4);
    		result[0] = 0;
    		result[1] = 0;
    		result[2] = 0;
    		result[3] = 0;
    
    		multmtrx(A, temp, result);
    		int *tempPointer;
    		tempPointer = result;
    		free(temp);
    		temp = tempPointer;
    		}
    }
    Sorry claudiu! I changed my main too.
    Code:
    int main()
    {
    	int sigma_x[2][2]={{0,1},{1,0}};
    	int ID[2][2]={{1,0},{0,1}};
    	int n;
    	int *temp;
    	
    	temp = (int*)malloc(sizeof(int) * 4);
    	temp[0] = 0;
    	temp[1] = 1;
    	temp[2] = 1;
    	temp[3] = 0;
    	
    	int *result;
    	
    	do {
    	
    		printf("\nHow many times do you want to multiply the matrix?\n");
    		printf("This returns A^n\n");
    		scanf("%d", &n);
    		
    		printf("\nThe matrix will be multiplied %d times.", n);
    		
    		expon(ID, n);
    		
    		printmtrx(temp);
    		
    		printf("\nAgain?");
    		scanf("%d", &n);
    		} 
    	while (n==1);
    	return 0;
    }

  7. #7
    Registered User
    Join Date
    May 2010
    Location
    Isla Vista
    Posts
    34
    Now the func doesn't do anything. Should I change void to int and return result or some other matrix? Then printmtrx(result);

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you want to start again from scratch, you must reinitialize your starting (temp) matrix inside the do-while loop, since that is what "reset the counter" means.

  9. #9
    Registered User
    Join Date
    May 2010
    Location
    Isla Vista
    Posts
    34
    Like this?
    Code:
    do {
    		temp = (int*)malloc(sizeof(int) * 4);
    		temp[0] = 0;
    		temp[1] = 0;
    		temp[2] = 0;
    		temp[3] = 0;
    If I change it to this, then it prints temp everytime instead of multiplying.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by bchudomelka View Post
    Like this?
    Code:
    do {
    		temp = (int*)malloc(sizeof(int) * 4);
    		temp[0] = 0;
    		temp[1] = 0;
    		temp[2] = 0;
    		temp[3] = 0;
    If I change it to this, then it prints temp everytime instead of multiplying.
    Except, of course, it does no such thing unless you deleted all the other code you had. (Hint: 0 times anything is still zero. Double hint: That isn't what you initialized temp to be the other times....)

  11. #11
    Registered User
    Join Date
    May 2010
    Location
    Isla Vista
    Posts
    34
    I'm lost. I see that by defining temp to be all zeroes, then it just outputs a zero matrix. Whatever I define temp as in main, that is what's returned. I'm not following your suggestions so well.

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Code:
    void main()
    {
    	int sigma_x[2][2]={{0,1},{1,0}};
    	int sigma_z[2][2]={{1,0},{0,-1}};
    	int ID[2][2]={{1,0},{0,1}};
    	int n;
    	int *temp;
    	
    	temp = (int*)malloc(sizeof(int) * 4);
    	temp[0] = 0;
    	temp[1] = 1;
    	temp[2] = 1;
    	temp[3] = 0; /*NOT INSIDE THE LOOP BAD BAD BAD*/	
    	int *result;
    	
    	do {
    	
    		printf("\nHow many times do you want to multiply the matrix?\n");
    		printf("This returns A^n\n");
    		scanf("%d", &n);
    		printf("\nThe matrix will be multiplied %d times.", n);
    
    		for (int i = 1; i < n; i++) {
    		result = (int*)malloc(sizeof(int) * 4);
    		result[0] = 0;
    		result[1] = 0;
    		result[2] = 0;
    		result[3] = 0;
    
    		multmtrx(sigma_x, temp, result);
    		int *tempPointer;
    		tempPointer = result;
    		free(temp);
    		temp = tempPointer;
    		}
    	
    		printmtrx(temp);
    		printf("\nAgain?");
    		scanf("%d", &n);
    		} 
    	while (n==1);
    }
    Notice how the red numbers are not 0.

  13. #13
    Registered User
    Join Date
    May 2010
    Location
    Isla Vista
    Posts
    34
    Yes!!! Thanks!!! Awesome!!! I have a follow up question...so now I have this main func that does A^n. To turn this into a func called expon...

    Hypothetically, I would..
    Code:
    int expon (int A[2][2], int n){
    int sigma_x[2][2]={{0,1},{1,0}};
    	int n;
    	int *temp;
    	
    	int *result;
    	
    	do {
    		temp = (int*)malloc(sizeof(int) * 4);
    		temp[0] = 0;
    		temp[1] = 1;
    		temp[2] = 1;
    		temp[3] = 0; 
    		
    	
    		for (int i = 1; i < n; i++) {
    		result = (int*)malloc(sizeof(int) * 4);
    		result[0] = 0;
    		result[1] = 0;
    		result[2] = 0;
    		result[3] = 0;
    
    		multmtrx(sigma_x, temp, result);
    		int *tempPointer;
    		tempPointer = result;
    		free(temp);
    		temp = tempPointer;
    		}
    	/* Does a return temp go here or a return *temp ? */
    }
    
    int main(){
    int n;
    int sigma_x[2][2]={{0,1},{1,0}};
    printf("\nHow many times do you want to multiply the matrix?\n");
    		printf("This returns A^n\n");
    		scanf("%d", &n);
    		printf("\nThe matrix will be multiplied %d times.", n);
                    expon(sigma_x, n);
                    printmtrx(temp);
    		printf("\nAgain?");
    		scanf("%d", &n);
    		} 
    		return 0;
    }

  14. #14
    Registered User
    Join Date
    May 2010
    Location
    Isla Vista
    Posts
    34
    Got the function. This is the code.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    void multmtrx(int A[2][2], int *B, int *result)
    {
    	for (int i=0; i<2; i++){
    		for (int j=0; j<2; j++)
    		for (int k=0; k<2; k++)
    			result[2*i+j]+=A[i][k]*B[2*k+j];}
    }
    
    void printmtrx(int *result)
    {
    	printf("\nThis is your new matrix.\n");
    	for (int i=0; i<2; i++)
    	{	for (int j=0; j<2; j++)
    		printf(" %d", result[2*i+j]);
    		printf("\n");
    	}
    }
    void expm(int A[2][2], int n){
    	int *temp;
    	
    	int *result;
    	
    	do {
    		temp = (int*)malloc(sizeof(int) * 4);
    		temp[0] = 0;
    		temp[1] = 1;
    		temp[2] = 1;
    		temp[3] = 0; 
    		
    		for (int i = 1; i < n; i++) {
    		result = (int*)malloc(sizeof(int) * 4);
    		result[0] = 0;
    		result[1] = 0;
    		result[2] = 0;
    		result[3] = 0;
    
    		multmtrx(A, temp, result);
    		int *tempPointer;
    		tempPointer = result;
    		free(temp);
    		temp = tempPointer;
    		}
    	
    		printmtrx(temp);
    		} 
    	while (n==1);
    	}
    
    int main()
    {
    	int sigma_x[2][2]={{0,1},{1,0}};
    	int n;	
    	start:
    	printf("\nHow many times do you want to multiply the matrix?\n");
    		printf("This returns A^n\n");
    		scanf("%d", &n);
    		printf("\nThe matrix will be multiplied %d times.", n);
    		expm(sigma_x, n);
    		printf("\nAgain?");
    		scanf("%d", &n);
    		if (n==1) {goto start;}	 
    		else
    	return 0;
    }
    Thanks for everyone's help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 02-18-2010, 11:17 AM
  2. C - access violation
    By uber in forum C Programming
    Replies: 2
    Last Post: 07-08-2009, 01:30 PM
  3. *operator overloading: scalar matrix multiplication
    By gemini_shooter in forum C++ Programming
    Replies: 4
    Last Post: 06-08-2009, 01:14 PM
  4. Matrix Help
    By HelpmeMark in forum C++ Programming
    Replies: 27
    Last Post: 03-06-2008, 05:57 PM