tidied up last issues
[The-Artvertiser.git] / artvertiser / matrixtracker.cpp
blobc8c5d9de9fc058d2d4874f32fdbc29abd25e8cc4
1 //==============================================================================
2 // Recursive definition of determinate using expansion by minors.
3 //
4 // Notes: 1) arguments:
5 // a (double **) pointer to a pointer of an arbitrary square matrix
6 // n (int) dimension of the square matrix
7 //
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
18 // possible etc.
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
22 // m n o p m n . p
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.
30 // m n
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
40 // free() calles.
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
52 // square array
54 if (n < 1) { } // error condition, should never get here
56 else if (n == 1) { // should not get here
57 det = a[0][0] ;
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
68 // sub matrix
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]
86 // a[1][2]
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
113 return(det) ;