GestureRecognitionToolkit  Version: 0.2.0
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
LUDecomposition.cpp
1 /*
2  GRT MIT License
3  Copyright (c) <2012> <Nicholas Gillian, Media Lab, MIT>
4 
5  Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6  and associated documentation files (the "Software"), to deal in the Software without restriction,
7  including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
9  subject to the following conditions:
10 
11  The above copyright notice and this permission notice shall be included in all copies or substantial
12  portions of the Software.
13 
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15  LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 
20  This code is based on the LU Decomposition code from Numerical Recipes (3rd Edition)
21 
22  */
23 
24 #define GRT_DLL_EXPORTS
25 #include "LUDecomposition.h"
26 
27 GRT_BEGIN_NAMESPACE
28 
29 LUDecomposition::LUDecomposition(const MatrixFloat &a) : sing(false){
30 
31  debugLog.setProceedingText("[DEBUG LUDecomposition]");
32  errorLog.setProceedingText("[ERROR LUDecomposition]");
33  warningLog.setProceedingText("[WARNING LUDecomposition]");
34 
35  N = a.getNumRows();
36  lu = a;
37  aref = a;
38  indx.resize( N );
39 
40  const Float TINY=1.0e-20;
41  unsigned int i,imax,j,k;
42  Float big,temp;
43  VectorFloat vv(N);
44  d=1.0;
45  imax = 0;
46  for (i=0;i<N;i++) {
47  big=0.0;
48  for (j=0;j<N;j++)
49  if ((temp=fabs( lu[i][j] )) > big) big=temp;
50  if (big == 0.0){
51  sing = true;
52  errorLog << "Error in LUDecomposition constructor, big == 0.0" << std::endl;
53  return;
54  }
55  vv[i] = 1.0/big;
56  }
57  for (k=0;k<N;k++) {
58  big=0.0;
59  for (i=k;i<N;i++) {
60  temp=vv[i]*fabs(lu[i][k]);
61  if (temp > big) {
62  big=temp;
63  imax=i;
64  }
65  }
66  if (k != imax) {
67  for (j=0;j<N;j++) {
68  temp=lu[imax][j];
69  lu[imax][j] = lu[k][j];
70  lu[k][j] = temp;
71  }
72  d = -d;
73  vv[imax]=vv[k];
74  }
75  indx[k]=imax;
76  if (lu[k][k] == 0.0) lu[k][k] = TINY;
77  for (i=k+1; i<N; i++) {
78  temp = lu[i][k] /= lu[k][k];
79  for (j=k+1;j<N;j++)
80  lu[i][j] -= temp * lu[k][j];
81  }
82  }
83 
84 }
85 
86 LUDecomposition::~LUDecomposition(){
87 
88 }
89 
90 bool LUDecomposition::solve_vector(const VectorFloat &b,VectorFloat &x)
91 {
92  int i=0,ii=0,ip=0,j=0; //This must be an int (as opposed to an UINT)
93  const int n = int(N);
94  Float sum=0;
95 
96  if (b.size() != N || x.size() != N){
97  errorLog << "solve_vector(const VectorFloat &b,VectorFloat &x) - the size of the two vectors does not match!" << std::endl;
98  return false;
99  }
100  for (i=0;i<n;i++) x[i] = b[i];
101  for (i=0;i<n;i++) {
102  ip=indx[i];
103  sum=x[ip];
104  x[ip] = x[i];
105  if (ii != 0)
106  for (j=ii-1;j<i;j++) sum -= lu[i][j] * x[j];
107  else if (sum != 0.0)
108  ii=i+1;
109  x[i]=sum;
110  }
111  for (i=n-1;i>=0;i--) {
112  sum=x[i];
113  for (j=i+1;j<n;j++) sum -= lu[i][j] * x[j];
114  x[i] = sum / lu[i][i];
115  }
116 
117  return true;
118 }
119 
120 bool LUDecomposition::solve(const MatrixFloat &b,MatrixFloat &x)
121 {
122  unsigned int m=b.getNumCols();
123  if (b.getNumRows() != N || x.getNumRows() != N || b.getNumCols() != x.getNumCols() ){
124  errorLog << "solve(const MatrixFloat &b,MatrixFloat &x) - the size of the two matrices does not match!" << std::endl;
125  return false;
126  }
127  VectorFloat xx(N);
128  for (unsigned int j=0; j<m; j++) {
129  for(unsigned int i=0; i<N; i++) xx[i] = b[i][j];
130  solve_vector(xx,xx);
131  for(unsigned int i=0; i<N; i++) x[i][j] = xx[i];
132  }
133  return true;
134 }
135 
136 bool LUDecomposition::inverse(MatrixFloat &ainv)
137 {
138  unsigned int i,j;
139  ainv.resize(N,N);
140  for (i=0;i<N;i++) {
141  for (j=0;j<N;j++) ainv[i][j] = 0.0;
142  ainv[i][i] = 1.0;
143  }
144  return solve(ainv,ainv);
145 }
146 
147 Float LUDecomposition::det()
148 {
149  Float dd = d;
150  for (unsigned int i=0;i<N;i++) dd *= lu[i][i];
151  return dd;
152 }
153 
154 bool LUDecomposition::mprove(const VectorFloat &b,VectorFloat &x)
155 {
156  unsigned int i,j;
157  VectorFloat r(N);
158  LongFloat sdp;
159  for (i=0;i<N;i++) {
160  sdp = -b[i];
161  for (j=0;j<N;j++)
162  sdp += (LongFloat) aref[i][j] * (LongFloat)x[j];
163  r[i]=sdp;
164  }
165  if( !solve_vector(r,r) ){
166  return false;
167  }
168  for (i=0;i<N;i++) x[i] -= r[i];
169  return true;
170 }
171 
172 bool LUDecomposition::getIsSingular(){
173  return sing;
174 }
175 
176 MatrixFloat LUDecomposition::getLU(){
177  return lu;
178 }
179 
180 GRT_END_NAMESPACE
unsigned int getNumRows() const
Definition: Matrix.h:542
unsigned int getNumCols() const
Definition: Matrix.h:549
virtual bool resize(const unsigned int r, const unsigned int c)
Definition: Matrix.h:232