0

Hello
I am trying to write a matrix calculator but I have some problems.I use cofactor method for calculation.If you don't know the this method you can learn it here easily: http://paulbourke.net/miscellaneous/determinant/
I use two function 1- GetMinor() 2- matrixCofactor() that the first one give me the minor matrix and I calculate determinant recursively in matrixCofactor() and print the determinant of the every matrix and its sub matrixes in every step. I don't know where the problem reside but I predict maybe problem be from recursive calls.I attach all my code file but I think this two function is enough for getting what is happening:

int GetMinor(Matrix *src,Matrix *dest, int row, int col, int order)
	{
	    // indicate which col and row is being copied to dest

	    int colCount = 0,rowCount = 0;
	    int i,j;

	    for(i = 0; i < order; i++ ){
	        if( i != row )
	        {
	            colCount = 0;
	            for( j = 0; j < order; j++ )
	            {
	                // when j is not the element
	                if( j != col )
	                {
	                    dest->elements[rowCount][colCount] = src->elements[i][j];
	                    colCount++;
	                }
	            }
	            rowCount++;
	        }
	    }
	    return 0;
	}

	int matrixCofact(Matrix* mat,int order,double* determinan){
		int i;
		Matrix* minor;
		minor = malloc(sizeof(double));
		newMatrix(order-1,order-1,minor);
		double* det;
		det = malloc(sizeof(double));
		if( order == 1 ){
			printf("The End");
		}
		for(i = 0; i <order;i++){
			GetMinor( mat, minor, 0, i, order);
			printf("\n");
			matrixPrint(minor);
			if( minor->colCount > 3){
				*det += pow(-1.0,i+0) * minor->elements[1][i] * matrixCofact(minor,order-1,det);
				printf("\nThe matrix determinant is: %f",*det);
			}else{
				matrix3dDeterminan(minor,det);
				printf("\nThe matrix determinant is: %f",*det);
			}
		}
		printf("BYE ");
		return 0;
	}
Attachments
/*
 * matrix
 *
 *  Created on: ????/?/?
 *      Author: Ali Keshvari
 */
#include<math.h>
typedef struct {
		int rowCount;
		int colCount;
		double** elements;
	}Matrix;

//	int matrixDeterminan(Matrix* m,int n,double* determinan);

	int newMatrix(int noRow,int noCol, Matrix* m){
		int i;
		m->rowCount = noRow;
		m->colCount = noCol;
		m->elements =(double **)malloc(m->rowCount * sizeof(double*));
		for( i =0 ; i < m->rowCount;i++){
			m->elements[i] =(double *)malloc(m->colCount * sizeof(double));
		}
		return 0;
		}
	int setMatrix(Matrix* m,int row,int col,double val){
		if( row > -1 && col > -1 && row < m->rowCount && col < m->colCount ){
		m->elements[row][col] = val;
		}
		return 0;
	}

	double matrixGet(Matrix *m,int r,int c,double* value){
		if( r > -1 && c > -1 && r < m->rowCount && c < m->colCount ){
		*value = m->elements[r][c];
		}
		return 0;
	}

	int inialMatrix(Matrix *m){
		int i,j;
		for(i = 0; i < m->rowCount;i++){
			for(j = 0 ; j < m->colCount;j++){
				m->elements[i][j] = 0.0;
			}
		}
		return 0;
	}

	int resizeMatrix(Matrix *m,int newNorow,int newNocol){
		int i;
		m->rowCount = m->rowCount * newNorow;
		m->colCount = m->colCount * newNocol;
		m->elements =(double **)realloc(m->elements,m->rowCount * sizeof(double*) * newNorow);
		for( i =0 ; i < m->rowCount;i++){
			m->elements[i] =(double *)realloc(m->elements[i],m->colCount * sizeof(double) * newNocol);
		}
		return 0;
	}
	int matrixDimmention(Matrix *m,int *r,int *c){
		*r = m->rowCount;
		*c = m->colCount;
		return 0;
	}

	void matrixPrint(Matrix *m){
		int i,j;
		for(i = 0; i < m->rowCount;i++){
			printf("\n");
			for(j = 0 ; j < m->colCount;j++){
				printf("%f\t",m->elements[i][j]);
			}
		}
	}
	void matrixFree(Matrix* m){
		free(m);
	}

	int matrixMultiply(Matrix *m1,Matrix *m2,Matrix *result){
		int i,j,k;
		int *r1;
		r1 = malloc(sizeof(int));
		int *c1;
		c1 = malloc(sizeof(int));
		int *r2;
		r2 = malloc(sizeof(int));
		int *c2;
		c2 = malloc(sizeof(int));
		if( *c1 != *r2){
			printf("operation not possible because  dimmentions are not compatible.");
			return 0;
		}
		for( i = 0 ; i < m1->rowCount  ; i++){
			for(j = 0 ; j < m2->colCount ;j++){
				for( k = 0 ; k < m1->rowCount ;k++){
					result->elements[i][j] += m1->elements[i][k] * m2->elements[k][j];
				}
			}
		}
		return 0;
	}
	int matrixDiv(Matrix *m1,Matrix *m2,Matrix *result){
		int i,j,k;
		int *r1;
		r1 = malloc(sizeof(int));
		int *c1;
		c1 = malloc(sizeof(int));
		int *r2;
		r2 = malloc(sizeof(int));
		int *c2;
		c2 = malloc(sizeof(int));
		if( *c1 != *r2){
			printf("operation not possible because  dimmentions are not compatible.");
			return 0;
		}
		for( i = 0 ; i < m1->rowCount  ; i++){
			for(j = 0 ; j < m2->colCount ;j++){
				for( k = 0 ; k < m1->rowCount ;k++){
					result->elements[i][j] += m1->elements[i][k] / m2->elements[k][j];
				}
			}
		}
		return 0;
	}
	int matrixAdd(Matrix *m1,Matrix *m2,Matrix *result){
			int i,j;
			int *r1;
			r1 = malloc(sizeof(int));
			int *c1;
			c1 = malloc(sizeof(int));
			int *r2;
			r2 = malloc(sizeof(int));
			int *c2;
			c2 = malloc(sizeof(int));
			if( (*c1 != *c2) || (*r1 = *r2)){
				printf("operation not possible because  dimmentions are not compatible.");
				return 0;
			}
			for( j =0 ; j < m1->colCount;j++){
				for( (i = 0) ; (i < m1->rowCount); (i++)){
					result->elements[i][i] = m1->elements[i][i] + m2->elements[i][i];
					result->elements[j][i] = m1->elements[j][i] + m2->elements[j][i];
				}
			}
			return 0;
	}

	int matrixSubtract(Matrix *m1,Matrix *m2,Matrix *result){
			int i,j;
			int *r1;
			r1 = malloc(sizeof(int));
			int *c1;
			c1 = malloc(sizeof(int));
			int *r2;
			r2 = malloc(sizeof(int));
			int *c2;
			c2 = malloc(sizeof(int));
			if( (*c1 != *c2) || (*r1 = *r2)){
				printf("operation not possible because  dimmentions are not compatible.");
				return 0;
			}
			for( j =0 ; j < m1->colCount;j++){
				for( (i = 0) ; (i < m1->rowCount); (i++)){
					result->elements[i][i] = m1->elements[i][i] - m2->elements[i][i];
					result->elements[j][i] = m1->elements[j][i] - m2->elements[j][i];
				}
			}
			return 0;
	}
	int matrixScalarmultply(Matrix* m,double value){
		int i,j;
		for(i = 0; i < m->rowCount;i++){
			for(j = 0 ; j < m->colCount;j++){
				m->elements[i][j] = m->elements[i][j] * value;
			}
		}
		return 0;
	}
	int matrix2dDeterminan(Matrix *m,double* determinan){
		if((m->rowCount > 3) || (m->colCount > 3)){
			printf("%s","The Matrix dimmension is not standard.");
			return 0;
		}
		*determinan = (m->elements[0][0]) * (m->elements[1][1]) - (m->elements[0][1])*(m->elements[1][0]);
		return 0;
	}
	int matrix3dDeterminan(Matrix *m,double* determinan){
		if((m->rowCount > 4) || (m->colCount > 4)){
			printf("%s","The Matrix dimmension is not standard.");
			return 0;
		}
		*determinan =
		 (m->elements[0][0]) * (m->elements[1][1]) * (m->elements[2][2])
		+  (m->elements[0][1]) * (m->elements[1][2]) * (m->elements[2][0])
		+  (m->elements[0][2]) * (m->elements[1][0]) * (m->elements[2][1])
		-  (m->elements[0][1]) * (m->elements[1][0]) * (m->elements[2][2])
		-  (m->elements[0][0]) * (m->elements[1][2]) * (m->elements[2][1])
		-  (m->elements[0][2]) * (m->elements[1][1]) * (m->elements[2][0]) ;
		return 0;
	}
//	int matrixMinorof(Matrix *m,int r,int c,double *minorof){
//		int i,j;
//		Matrix* M;
//		M = malloc(sizeof(Matrix));
//		int* row;
//		row = malloc(sizeof(double));
//		int* col;
//		col = malloc(sizeof(double));
//		matrixDimmention(m,row,col);
//		int noCol,noRow;
//		noCol = *col;//newMatrix inputs
//		noRow = *row;
//    	newMatrix(noRow-1,noCol-1,M);
//    	int p,q;
//		for(i= 0 ;i < m->rowCount;i++){
//			if( i != r){
//				q = 0;
//				for( j= 0;j < m->colCount ; j++){
//					if( j != c){
//						M->elements[p][q] = m->elements[i][j];
//					}
//					q++;
//				}
//				p++;
//			}
//		}


//		for(i = 0; i < r;i++){
//			for(j = 0 ; j < c;j++){
//				M->elements[i][j] = m->elements[i][j];
//			}
//			for(j = c ; j < m->colCount-1;j++){
//				M->elements[i][j] = m->elements[i][j+1];
//			}
//		}
//		for(i = r+1; i < m->rowCount ;i++){
//			for(j = 0 ; j < c;j++){
//			M->elements[i-1][j] = m->elements[i][j];
//			}
//			for(j = c ; j < m->colCount-1;j++){
//			M->elements[i-1][j] = m->elements[i][j+1];
//			}
//		}

//		if( (M->colCount > 3) || (M->rowCount > 3) ){
//			double* deter;
//			deter = malloc(sizeof(double*));
//			matrixDeterminan(M,1,deter);
//    	}
		//matrixDeterminan(M,1,minorof);
//		if( (M->rowCount = 3) || (M->colCount = 3) ){
//			matrix3dDeterminan(M,minorof);
//		}
	//	printf("%f\n",*minorof);
//		printf("\n");
//		matrixPrint(M);
//		printf("\n");

//		if( (M->colCount = 2) || (M->rowCount = 2) ){
//			matrix2dDeterminan(M,minorof);
//		}

//		if( (M->colCount = 1) || (M->rowCount = 1)){
//			*minorof = M->elements[1][1];
//		}
//	return 0;
//	}

//	int matrixDeterminan(Matrix* m,int n,double* determinan){
//
//		double* minor;
//		minor = malloc(sizeof(Matrix));
//		int i;
//		double* result;
//		result = malloc(sizeof(double));
//		//newMatrix((m->rowCount)-1,(m->colCount)-1,minor);
//		if(m->rowCount < 1){
//			return 0;
//		}
//		if(m->rowCount == 1){
//			return m->elements[0][0];
//		}
//
//		for(i = 0 ;i < m->rowCount;i++){
//			if(!matrixMinorof(m,n,i,minor))
//				return 0;
//			*result += (pow(-1,i)*m->elements[n][i]*matrixDeterminan(minor,1,result));
//		}
//		*determinan= *result;
//		return 0;
//	}





	int GetMinor(Matrix *src,Matrix *dest, int row, int col, int order)
	{
	    // indicate which col and row is being copied to dest

	    int colCount = 0,rowCount = 0;
	    int i,j;

	    for(i = 0; i < order; i++ ){
	        if( i != row )
	        {
	            colCount = 0;
	            for( j = 0; j < order; j++ )
	            {
	                // when j is not the element
	                if( j != col )
	                {
	                    dest->elements[rowCount][colCount] = src->elements[i][j];
	                    colCount++;
	                }
	            }
	            rowCount++;
	        }
	    }
	    return 0;
	}




	int matrixCofact(Matrix* mat,int order,double* determinan){
		int i;
		Matrix* minor;
		minor = malloc(sizeof(double));
		newMatrix(order-1,order-1,minor);
		double* det;
		det = malloc(sizeof(double));
		if( order == 1 ){
			printf("The End");
		}
		for(i = 0; i <order;i++){
			GetMinor( mat, minor, 0, i, order);
			printf("\n");
			matrixPrint(minor);
			if( minor->colCount > 3){
				*det += pow(-1.0,i+0) * minor->elements[1][i] * matrixCofact(minor,order-1,det);
				printf("\nThe matrix determinant is: %f",*det);
			}else{
				matrix3dDeterminan(minor,det);
				printf("\nThe matrix determinant is: %f",*det);
			}
		}
		printf("BYE ");
		return 0;
	}


//	double Determinant(Matrix *a,int n)
//	{
//	   int i,j,j1,j2;
//	   double det = 0;
//	   Matrix * m = NULL;
//
//	   if (n < 1) { /* Error */
//
//	   } else if (n == 1) { /* Shouldn't get used */
//	      det = a->elements[0][0];
//	   } else if (n == 2) {
//	      det = a->elements[0][0] * a->elements[1][1] - a->elements[1][0] * a->elements[0][1];
//	   } else {
//	      det = 0;
//	         for (i=1;i<n;i++) {
//	            j2 = 0;
//	            for (j=0;j<n;j++) {
//	               if (j == j1)
//	                  continue;
//	               m->elements[i-1][j2] = a->elements[i][j];
//	               j2++;
//	            }
//	         det += pow(-1.0,1.0+j1+1.0) * a->elements[0][j1] * Determinant(m,n-1);
//	      }
//	   }
//	   return(det);
//	}


//	int matrixMinor(Matrix* m,int r,int c,double* determinan){
//		if(m->rowCount == 2 && m->colCount == 2){
//			matrix2dDeterminan(m,determinan);
//		}
//		Matrix* M;
//		M = malloc(sizeof(Matrix));
//		newMatrix(m->rowCount-1,m->colCount-1,M);
//		int i,j;
//		int p;
//		int q;
//		p = 0;
//		q = 0;
//		r = r - 1;
//		c = c - 1;
//		for(i = 0 ; i < m->rowCount;i++){
//			p = i;
//			if( i == r){
//				--(p);
//				continue;
//			}
////			}else{
////				++(p);
////			}
//			for(j = 0 ;j < m->colCount;j++){
//				q = j;
//				if( j == c){
//					--(q);
//					continue;
//				}
////				}else{
////					++(q);
////				}
//				M->elements[p][q] = m->elements[i][j];
//			}
//		}
//		printf("\nThe minor matrix is:\n");
//		matrixPr
/*
 ============================================================================
 Name        : Vector-Marix.c
 Author      : Ali Keshvari
 Version     :
 Copyright   : 
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include "vector.h"
#include "matrix.h"

int main(void) {
			//*****Vector test*****//
//	Vector* v1;
//	v1 = malloc(sizeof(Vector));
//	newVector(3,v1);
//	vectorSet(v1,0,1.1);
//	vectorSet(v1,1,2.1);
//	vectorSet(v1,2,3.1);
//	Vector* v2;
//	v2 = malloc(sizeof(Vector));
//	newVector(3,v2);
//	vectorSet(v2,0,2.2);
//	vectorSet(v2,1,3.2);
//	vectorSet(v2,2,4.2);
//	double* result1;
//	result1 = malloc(sizeof(double));
//	innerProductofvectors(v1,v2,result1);
//	printf("%f\n",*result1);
//	Vector* result2;
//	result2 = malloc(sizeof(Vector));
//	newVector(3,result2);
//	crossProductofvectors(v1,v2,result2);
//	vectorPrint(result2);
//	vectorPrint(v2);
//	freeVector(v1);
//	freeVector(v2);
//	free(result1);
//	freeVector(result2);
			//*****Matrix test*****//
		Matrix* m2;
	m2 = malloc(sizeof(Matrix));
	newMatrix(6,6,m2);

	setMatrix(m2,0,0,1.0);
	setMatrix(m2,0,1,-4.0);
	setMatrix(m2,0,2,2.0);
	setMatrix(m2,0,3,1.0);
	setMatrix(m2,0,4,3.0);
	setMatrix(m2,0,5,-1.0);

	setMatrix(m2,1,0,2.0);
	setMatrix(m2,1,1,4.0);
	setMatrix(m2,1,2,1.0);
	setMatrix(m2,1,3,4.0);
	setMatrix(m2,1,4,3.0);
	setMatrix(m2,1,5,5.0);

	setMatrix(m2,2,0,7.0);
	setMatrix(m2,2,1,8.0);
	setMatrix(m2,2,2,6.0);
	setMatrix(m2,2,3,2.0);
	setMatrix(m2,2,4,3.0);
	setMatrix(m2,2,5,5.0);

	setMatrix(m2,3,0,3.0);
	setMatrix(m2,3,1,2.0);
	setMatrix(m2,3,2,4.0);
	setMatrix(m2,3,3,1.0);
	setMatrix(m2,3,4,5.0);
	setMatrix(m2,3,5,2.0);

	setMatrix(m2,4,0,3.0);
	setMatrix(m2,4,1,4.0);
	setMatrix(m2,4,2,2.0);
	setMatrix(m2,4,3,1.0);
	setMatrix(m2,4,4,5.0);
	setMatrix(m2,4,5,2.0);

	setMatrix(m2,5,0,1.0);
	setMatrix(m2,5,1,2.0);
	setMatrix(m2,5,2,3.0);
	setMatrix(m2,5,3,6.0);
	setMatrix(m2,5,4,4.0);
	setMatrix(m2,5,5,5.0);
	printf("The matrix is:");
	matrixPrint(m2);
	printf("\n");
//	printf("\n%s","Hello world");
//	Matrix* minor;
//	minor = malloc(sizeof(Matrix));
//	newMatrix(5,5,minor);
//	double* determinan;
//	determinan = malloc(sizeof(double));
//	matrixCofact(m2,6,determinan);
//	printf("\nThe matrix is:%f",*determinan);
//
//	matrixdeterminan(m2,6);
	return EXIT_SUCCESS;
}
3
Contributors
3
Replies
6
Views
5 Years
Discussion Span
Last Post by keshvari
0

I don't see anything obvious, but I'm not familiar with this, either.

If I were starting to debug it, I'd probably start with assertions to check that all the indices are staying within their proper ranges. Then start checking the subtotals, and whether j=0 is correct, for it's initialization (or should it be j=i?).
Should newmatrix be set to order-1?, etc.

There are lots of examples of this kind of code, but I don't know if it uses the cofactor method or not.

Edited by Adak: n/a

1

At line 42 you call matrixCofact as if it returns the minor's determinant. I recommend to (a) make matrixCofact return double, (b) get rid of its third parameter (you don't use it anyway), and (c) change line 50 to return det . Of course, det should be just double (not a pointer).
PS: minor->elements at line 52 is wrong. It should be mat->elements[0].
PPS: You probably know that it is one of the least efficient algorithms.

0

Hello
nezachem really thanks for your guide it was helpful. Another problem of my code is at line 41:

if( minor->colCount > 3)

it should be change to

if( order <3 )

because minor row and col amount is 1 less than order at every step because of this code

newMatrix(order-1,order-1,minor)
This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.