Help me with this C program to calculate matrix determinant

CA50

Skilled
Please help me with this code to calclualte the determinant of a matrix using column operation. The problem is when the element r3c3 (assuming it to be a 3x3 matrix) has to be converted to 0


Code:
/*FUNCTION TO CALCULATE THE DETERMINANT OF A MATRIX
PARAMETER  : SINGLE VALUE OF ROW AND COL IS PASSED, AS FOR ALL THE MATRIX, THE VALUE OF ROW AND COL WILL BE SAME | IN ALL THE CASE THE COLOUMN VALUE IS MANDATORY SO ITS SET TO 'col', WHICH IS AGAIN PREDEFINED*/
float matrix_determinant(int row, float matrix[][row])
{
	int i, j, k,flag=0,counter,count;
	float determinant=0,temp,element;
	for(i=0; i<row; i++)
	{
        flag=0;
		for(j=0; j<row; j++)
		{
			//counter++;
			if(i == j)
			{ 
				temp =  1 / matrix[i][j];
				determinant = determinant + temp;
				counter = i;
				for(k=0; k<row; k++)
				{
					printf("\nRow-%d,Col-%d : %f = %f * %f ",i,k,matrix[i][k],matrix[i][k],temp);
					matrix[i][k] = matrix[i][k] * temp;
                }
				break;
             } 
             
			if((i>j) && (flag == 0))
			{
				temp = matrix[i][j];
				printf("\n\nValue of the term to be multiplied : %f\n",temp);
				for(k=0; k<row; k++)
				{
					printf("\nRow-%d,Col-%d : %f = %f - (%f * %f)",i,k,matrix[i][k],matrix[i][k],temp,matrix[counter][k]);
					matrix[i][k] = matrix[i][k] - (temp * matrix[counter][k]);
				}
				printf("\n.........................................\n");
	         	matrix_display(row, matrix);
				flag = 1;
			}
		}
		printf("\n-----------------------------------------\n");
		matrix_display(row, matrix);
	}
	return determinant;
}
 
I don't see any division by the matrix members required for the calculation here.
Determinant - Wikipedia, the free encyclopedia

What formula are you using to calculate the determinant?

Post the entire code with the main() function.


I am trying to implement row-operation, as shown here
Linear Algebra Toolkit


here is the complete code

Code:
/*Program to calculate the detreminant of a sqaure matrix*/
#include<stdio.h>

//FUNCTION DEFINATION FOR MATIRX INPUT, DISPLAY AND DETERMINANT
//TIP FOR MATRIX INPUT & DISPLAY : HERE THE ROW AND COL ARE PASSED PRIOR TO THE MATRIX, BECAUSE IN CASE OF MATRIX, THE COLUMN FIELD IS MANDATORY SO, IT IS DECLARED FIRST AND USED IN THE MATRIX ITSELF

void matrix_input(int, float [][]);
void matrix_display(int, float [][]);
float matrix_determinant(int, float [][]);

//STARTING MAIN() FUNCTION
int main()
{
	printf("\n\nPROGRAM TO CALCULATE THE DETERMINANT OF A SQUARE MATRIX\n\n");
	//INITIALIZING ROW AND COL FOR BOTH THE MATRIX
	int row,col;
	float deterninamt;
 printf("Enter the size of the matrix (row and col) : ");
	scanf("%d%d",&row,&col);
	
	//CHECKING OF THE MATRIX IS SQAURE OR NOT ??
	//IF YES THEN THE MATRIXES ARE INITIALISED
	if(row == col)
	{
		float matrix[row][col], determinant;
		//GETTING INPUT FOR THE FIRST MARTIX | PASSING THE ROW, COL & MATRIX NAME
		printf("\nEnter elements for MATRIX 1 (%dx%d), row-wise :",row,col);
		matrix_input(row, matrix);

		
		//CALLING THE DISPLAY_MATRIX FUNCTION : PASSING ROW, COL AND NAME OF MATRIX
		printf("\nGiven matrix (%dx%d) :\n",row,col);
		matrix_display(row, matrix);
		
		determinant = matrix_determinant(row, matrix);
		printf("\nAfter processing (%dx%d) :\n",row,col);
		matrix_display(row, matrix);
		
		printf("\n\nDeterminant = %f",determinant);
		
		
	}
	//DISPLAYING ERROR INCASE OF MIS-MATCH MATRIX SIZE
	else
		printf("\n\nFor calculating the determinant of a matrix, the martix must be a SQUARE MATRIX.");
	printf("\n\n");
	getch();
	return 0;
}
//END OF MAIN FUNCTION



/*FUNCTION TO FILL A SQUARE MATRIX
PARAMTER: ROW, COL, MATRIX NAME | INCASE OF A SQUARE MATRIX, THE ROW AND COL ARE SAME, SO ONLY ONE VALUE IS PASSED TO REDUCE MEMORY CONSUMPTION,
ALSO THE COLUMN NAME OF THE MATRIX IS MANDATORY SO THE VARIABLE 'row' IS USED.*/
void matrix_input(int row, float matrix[][row])
{
	int i,j,choice;
	printf("\nChoose matrix filling type : \n\t1. Manual Fill\n\t2. Auto Fill (1-100)\n");
	scanf("%d",&choice);
	//MANUAL FILL | GETTING ELEMENT FROM KEYBORAD FEED BY THE USER
	if(choice == 1)
	{
 	//HERE ROWS AND COLS ARE EQUAL, SO 'row' IS USED IN BOTH THE LOOPS
		for(i=0; i<row; i++)
			for(j=0; j<row; j++)
			{
				printf("Enter element for row-%d, col-%d : ",i+1,j+1);
				scanf("%f", &matrix[i][j]);
			}
	}
 //AUTO FILL | GETTING ELEMENT GENERATED BY THE RAND()
	else
	{
		for(i=0; i<row; i++)
			for(j=0; j<row; j++)
			{
				choice = rand() % 10+1;
				printf("Enter element for row-%d, col-%d : %d\n",i+1,j+1, choice);
				matrix[i][j] = choice;
			}
	}
}
//END OF MATRIX_INPUT FUNCTION


/*FUNCTION TO DISPLAY A SQUARE SQUARE_MATRIX | INCASE OF A SQUARE MATRIX THE ROW AND COL ARE EQUAL, SO ONLY ONE PARAMETER IS USED*/
void matrix_display(int row, float matrix[][row])
{
	//HERE ROWS AND COLS ARE EQUAL, SO 'row' IS USED IN BOTHETHE LOOPS
	int i, j;
	for(i=0; i<row; i++)
	{
		for(j=0; j<row; j++)
			printf(" %5.2f  ",matrix[i][j]);
		printf("\n");
    }
}
//END OF FUNCTION TO DISPLAY A SQUARE_MATRIX


/*FUNCTION TO CALCULATE THE DETERMINANT OF A MATRIX
PARAMETER  : SINGLE VALUE OF ROW AND COL IS PASSED, AS FOR ALL THE MATRIX, THE VALUE OF ROW AND COL WILL BE SAME | IN ALL THE CASE THE COLOUMN VALUE IS MANDATORY SO ITS SET TO 'col', WHICH IS AGAIN PREDEFINED*/
float matrix_determinant(int row, float matrix[][row])
{
	int i, j, k,flag=0,counter,count;
	float determinant=0,temp,element;
	for(i=0; i<row; i++)
	{
        flag=0;
		for(j=0; j<row; j++)
		{
			//counter++;
			if(i == j)
			{ 
				temp =  1 / matrix[i][j];
				determinant = determinant + temp;
				counter = i;
				for(k=0; k<row; k++)
				{
					printf("\nRow-%d,Col-%d : %f = %f * %f ",i,k,matrix[i][k],matrix[i][k],temp);
					matrix[i][k] = matrix[i][k] * temp;
                }
				break;
             } 
             
			if((i>j) && (flag == 0))
			{
				temp = matrix[i][j];
				printf("\n\nValue of the term to be multiplied : %f\n",temp);
				for(k=0; k<row; k++)
				{
					printf("\nRow-%d,Col-%d : %f = %f - (%f * %f)",i,k,matrix[i][k],matrix[i][k],temp,matrix[counter][k]);
					matrix[i][k] = matrix[i][k] - (temp * matrix[counter][k]);
				}
				printf("\n.........................................\n");
	         	matrix_display(row, matrix);
				flag = 1;
			}
		}
		printf("\n-----------------------------------------\n");
		matrix_display(row, matrix);
	}
	return determinant;
}

- - - Updated - - -
@mathrisk
 
Last edited by a moderator:
What IDE do you use to develop? If you are able to singlestep in the code and check variables you could solve this yourself.



suggestions to get this working.

calculations for r1c1, r2c1 and r2c2 are working fine.

r3c1 gets calculated wrongly because the value of counter is not initialized in the if((i>j) && (flag == 0)) loop. Solve this.

r3c2 calculation is completely skipped because of improper use of flag variable. Check whether you need the flag variable.

This will give you a proper row-echelon form, but the determinant value will still be wrong. Modify this statement to remedy this. determinant = determinant + temp;

Another issue with the code is when you calculate temp = 1 / matrix[ i ][ j ]; You need to add a check for not dividing by zero. The value of the determinant will also be impacted when matrix[ i ][ j ] is zero. For an example, use the following matrix {{1,2,3},{4,5,6},{7,8,9}};



I've given enough hints to solve this yourself. If you don't understand anything of the above, post with specific query and what else you tried as an alternative.
 
What IDE do you use to develop? If you are able to singlestep in the code and check variables you could solve this yourself.

I am using DevC++

suggestions to get this working.

calculations for r1c1, r2c1 and r2c2 are working fine.

r3c1 gets calculated wrongly because the value of counter is not initialized in the if((i>j) && (flag == 0)) loop. Solve this.
How to solve this? Actually i am stuck in this :(/

r3c2 calculation is completely skipped because of improper use of flag variable. Check whether you need the flag variable.
Flag is necessary because in certain case, value of i might be equal and in the next loop it might be equal to j, but at a time only one row operations should be done so

This will give you a proper row-echelon form, but the determinant value will still be wrong. Modify this statement to remedy this. determinant = determinant + temp;
Can you please explain this

Another issue with the code is when you calculate temp = 1 / matrix[ i ][ j ]; You need to add a check for not dividing by zero. The value of the determinant will also be impacted when matrix[ i ][ j ] is zero. For an example, use the following matrix {{1,2,3},{4,5,6},{7,8,9}};
Will fix that


I've given enough hints to solve this yourself. If you don't understand anything of the above, post with specific query and what else you tried as an alternative.


thanks mate, i have replied in bold
 
If this query is resolved then I have one different query to ask.

How we can search Sub-matrix in a given Matrix ?

I mean best way or which takes lesser iteration & less time.

Thanks in advance for the coders/analyst/architect sitting here.
 
CA50

regarding counter
r3c1 calculation requires you to subtract (r3c1*Row 1) from Row 3. Similarly
r3c2 calculation requires you to subtract (r3c2*Row 2) from Row 3.
The bold part is what you need to initialize counter to depending on the current values of i,j.
You are actually initializing it in the if(i == j) loop but it is of no use there. That actually helps in r2c1 calculations but fails for all the other rows.


regarding flag
Your if statements are sufficient enough checkpoints. I removed the flag variable completely and the code is working fine.
Actually the following for loop organization would have been better instead of the current one.
Code:
for(i=0; i<row; i++)
{[INDENT]for(j=0; j<=i; j++)[/INDENT]
[INDENT]{[/INDENT]
[INDENT=2]if(i == j)
{[/INDENT]
[INDENT=3]//calculate r1c1,r2c2,r3c3,.....[/INDENT]
[INDENT=2]}
else//j<i calculations
{[/INDENT]
[INDENT=3]//calculate r2c1,r3c1,r3c2,........
[/INDENT]
[INDENT=2]}[/INDENT]
[INDENT]}[/INDENT]
}



regarding determinant calculation.
Check the link that you yourself provided. The determinant is calculated using multiplications and not by additions.


haris5sani
do you mean to find the sub-matrix by eliminating a single row+column depending on the current matrix element?
 
haris5sani
do you mean to find the sub-matrix by eliminating a single row+column depending on the current matrix element?
I didn't get you what you are saying.
I want to search a sub-matrix like 3 X 3 matrix in a 100 X 100 matrix, in an efficient way.

I dont want to compare each matrix by comparing each value, so is there any alternate good method to make this process efficient ?
 
@haris5sani
can you make a new thread so that we don't go too OT in this one? Also post the exact query with possible examples so that you can get a targeted solution.

What you are asking comes under theoretical/algorithmic optimization. If you have to make multiple searches for 3x3 matrices then you could look at 'hashing' the 3x3 matrices of 100x100 matrix. This will reduce comparisons but the creation of hash indices will take time hence it is suggested for multiple searches. Language specific optimizations can also be applied. I'll expand on this in the new post.

Keep in mind that compiler optimizations are very good and will make your 'each value search' loops fast enough. This is why you won't notice much difference if you try to tweak your implementation. Trying an altogether different approach like hashing will yield different results.
 
Last edited by a moderator:
Back
Top