1 //==============================================================================
2 // Recursive definition of determinate using expansion by minors.
4 // Notes: 1) arguments:
5 // a (double **) pointer to a pointer of an arbitrary square matrix
6 // n (int) dimension of the square matrix
8 // 2) Determinant is a recursive function, calling itself repeatedly
9 // each time with a sub-matrix of the original till a terminal
10 // 2X2 matrix is achieved and a simple determinat can be computed.
11 // As the recursion works backwards, cumulative determinants are
12 // found till untimately, the final determinate is returned to the
13 // initial function caller.
15 // 3) m is a matrix (4X4 in example) and m13 is a minor of it.
16 // A minor of m is a 3X3 in which a row and column of values
17 // had been excluded. Another minor of the submartix is also
19 // m a b c d m13 . . . .
20 // e f g h e f . h row 1 column 3 is elminated
21 // i j k l i j . l creating a 3 X 3 sub martix
24 // 4) the following function finds the determinant of a matrix
25 // by recursively minor-ing a row and column, each time reducing
26 // the sub-matrix by one row/column. When a 2X2 matrix is
27 // obtained, the determinat is a simple calculation and the
28 // process of unstacking previous recursive calls begins.
31 // o p determinant = m*p - n*o
33 // 5) this function uses dynamic memory allocation on each call to
34 // build a m X m matrix this requires ** and * pointer variables
35 // First memory allocation is ** and gets space for a list of other
36 // pointers filled in by the second call to malloc.
38 // 6) C++ implements two dimensional arrays as an array of arrays
39 // thus two dynamic malloc's are needed and have corresponsing
42 // 7) the final determinant value is the sum of sub determinants
44 //==============================================================================
47 double Determinant(double **a
,int n
)
49 int i
,j
,j1
,j2
; // general loop and matrix subscripts
50 double det
= 0 ; // init determinant
51 double **m
= NULL
; // pointer to pointers to implement 2d
54 if (n
< 1) { } // error condition, should never get here
56 else if (n
== 1) { // should not get here
60 else if (n
== 2) { // basic 2X2 sub-matrix determinate
61 // definition. When n==2, this ends the
62 det
= a
[0][0] * a
[1][1] - a
[1][0] * a
[0][1] ;// the recursion series
66 // recursion continues, solve next sub-matrix
67 else { // solve the next minor by building a
69 det
= 0 ; // initialize determinant of sub-matrix
71 // for each column in sub-matrix
72 for (j1
= 0 ; j1
< n
; j1
++) {
73 // get space for the pointer list
74 m
= (double **) malloc((n
-1)* sizeof(double *)) ;
76 for (i
= 0 ; i
< n
-1 ; i
++)
77 m
[i
] = (double *) malloc((n
-1)* sizeof(double)) ;
78 // i[0][1][2][3] first malloc
79 // m -> + + + + space for 4 pointers
80 // | | | | j second malloc
81 // | | | +-> _ _ _ [0] pointers to
82 // | | +----> _ _ _ [1] and memory for
83 // | +-------> _ a _ [2] 4 doubles
84 // +----------> _ _ _ [3]
87 // build sub-matrix with minor elements excluded
88 for (i
= 1 ; i
< n
; i
++) {
89 j2
= 0 ; // start at first sum-matrix column position
90 // loop to copy source matrix less one column
91 for (j
= 0 ; j
< n
; j
++) {
92 if (j
== j1
) continue ; // don't copy the minor column element
94 m
[i
-1][j2
] = a
[i
][j
] ; // copy source element into new sub-matrix
95 // i-1 because new sub-matrix is one row
96 // (and column) smaller with excluded minors
97 j2
++ ; // move to next sub-matrix column position
101 det
+= pow(-1.0,1.0 + j1
+ 1.0) * a
[0][j1
] * Determinant(m
,n
-1) ;
102 // sum x raised to y power
103 // recursively get determinant of next
104 // sub-matrix which is now one
105 // row & column smaller
107 for (i
= 0 ; i
< n
-1 ; i
++) free(m
[i
]) ;// free the storage allocated to
108 // to this minor's set of pointers
109 free(m
) ; // free the storage for the original
110 // pointer to pointer