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.
Derivative.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 
21 #define GRT_DLL_EXPORTS
22 #include "Derivative.h"
23 
24 GRT_BEGIN_NAMESPACE
25 
26 //Register the Derivative module with the PreProcessing base class
27 RegisterPreProcessingModule< Derivative > Derivative::registerModule("Derivative");
28 
29 Derivative::Derivative(UINT derivativeOrder,Float delta,UINT numDimensions,bool filterData,UINT filterSize){
30  classType = "Derivative";
31  preProcessingType = classType;
32  debugLog.setProceedingText("[DEBUG Derivative]");
33  errorLog.setProceedingText("[ERROR Derivative]");
34  warningLog.setProceedingText("[WARNING Derivative]");
35  if( derivativeOrder == FIRST_DERIVATIVE || derivativeOrder == SECOND_DERIVATIVE ){
36  init(derivativeOrder,delta,numDimensions,filterData,filterSize);
37  }
38 }
39 
41 
42  this->derivativeOrder = rhs.derivativeOrder;
43  this->filterSize = rhs.filterSize;
44  this->delta = rhs.delta;
45  this->filterData = rhs.filterData;
46  this->filter = rhs.filter;
47  this->yy = rhs.yy;
48  this->yyy = rhs.yyy;
49 
50  classType = "Derivative";
51  preProcessingType = classType;
52  debugLog.setProceedingText("[DEBUG Derivative]");
53  errorLog.setProceedingText("[ERROR Derivative]");
54  warningLog.setProceedingText("[WARNING Derivative]");
55 
57 }
58 
60 
61 }
62 
64  if( this != &rhs ){
65  this->derivativeOrder = rhs.derivativeOrder;
66  this->filterSize = rhs.filterSize;
67  this->delta = rhs.delta;
68  this->filterData = rhs.filterData;
69  this->filter = rhs.filter;
70  this->yy = rhs.yy;
71  this->yyy = rhs.yyy;
73  }
74  return *this;
75 }
76 
77 bool Derivative::deepCopyFrom(const PreProcessing *preProcessing){
78 
79  if( preProcessing == NULL ) return false;
80 
81  if( this->getPreProcessingType() == preProcessing->getPreProcessingType() ){
82 
83  Derivative *ptr = (Derivative*)preProcessing;
84 
85  //Clone the Derivative values
86  this->derivativeOrder = ptr->derivativeOrder;
87  this->filterSize = ptr->filterSize;
88  this->delta = ptr->delta;
89  this->filterData = ptr->filterData;
90  this->filter = ptr->filter;
91  this->yy = ptr->yy;
92  this->yyy = ptr->yyy;
93 
94  //Clone the base class variables
95  return copyBaseVariables( preProcessing );
96  }
97 
98  errorLog << "clone(const PreProcessing *preProcessing) - PreProcessing Types Do Not Match!" << std::endl;
99 
100  return false;
101 }
102 
103 bool Derivative::process(const VectorFloat &inputVector){
104 
105  if( !initialized ){
106  errorLog << "process(const VectorFloat &inputVector) - Not initialized!" << std::endl;
107  return false;
108  }
109 
110  if( inputVector.getSize() != numInputDimensions ){
111  errorLog << "process(const VectorFloat &inputVector) - The size of the inputVector (" << inputVector.size() << ") does not match that of the filter (" << numInputDimensions << ")!" << std::endl;
112  return false;
113  }
114 
115  computeDerivative( inputVector );
116 
117  if( processedData.size() == numOutputDimensions ) return true;
118  return false;
119 }
120 
122  if( initialized ) return init(derivativeOrder, delta, numInputDimensions,filterData,filterSize);
123  return false;
124 }
125 
126 bool Derivative::save(std::fstream &file) const{
127 
128  if( !file.is_open() ){
129  errorLog << "save(fstream &file) - The file is not open!" << std::endl;
130  return false;
131  }
132 
133  file << "GRT_DERIVATIVE_FILE_V1.0" << std::endl;
134 
135  file << "NumInputDimensions: " << numInputDimensions << std::endl;
136  file << "NumOutputDimensions: " << numOutputDimensions << std::endl;
137  file << "DerivativeOrder: " << derivativeOrder << std::endl;
138  file << "FilterSize: " << filterSize << std::endl;
139  file << "Delta: " << delta << std::endl;
140  file << "FilterData: " << filterData << std::endl;
141 
142  return true;
143 }
144 
145 bool Derivative::load(std::fstream &file){
146 
147  if( !file.is_open() ){
148  errorLog << "load(fstream &file) - The file is not open!" << std::endl;
149  return false;
150  }
151 
152  std::string word;
153 
154  //Load the header
155  file >> word;
156 
157  if( word != "GRT_DERIVATIVE_FILE_V1.0" ){
158  errorLog << "load(fstream &file) - Invalid file format!" << std::endl;
159  return false;
160  }
161 
162  //Load the number of input dimensions
163  file >> word;
164  if( word != "NumInputDimensions:" ){
165  errorLog << "load(fstream &file) - Failed to read NumInputDimensions header!" << std::endl;
166  return false;
167  }
168  file >> numInputDimensions;
169 
170  //Load the number of output dimensions
171  file >> word;
172  if( word != "NumOutputDimensions:" ){
173  errorLog << "load(fstream &file) - Failed to read NumOutputDimensions header!" << std::endl;
174  return false;
175  }
176  file >> numOutputDimensions;
177 
178  //Load the DerivativeOrder
179  file >> word;
180  if( word != "DerivativeOrder:" ){
181  errorLog << "load(fstream &file) - Failed to read DerivativeOrder header!" << std::endl;
182  return false;
183  }
184  file >> derivativeOrder;
185 
186  //Load the FilterSize
187  file >> word;
188  if( word != "FilterSize:" ){
189  errorLog << "load(fstream &file) - Failed to read FilterSize header!" << std::endl;
190  return false;
191  }
192  file >> filterSize;
193 
194  //Load the Delta
195  file >> word;
196  if( word != "Delta:" ){
197  errorLog << "load(fstream &file) - Failed to read Delta header!" << std::endl;
198  return false;
199  }
200  file >> delta;
201 
202  //Load if the data should be filtered
203  file >> word;
204  if( word != "FilterData:" ){
205  errorLog << "load(fstream &file) - Failed to read FilterData header!" << std::endl;
206  return false;
207  }
208  file >> filterData;
209 
210  //Init the derivative module to ensure everything is initialized correctly
211  return init(derivativeOrder,delta,numInputDimensions,filterData,filterSize);
212 }
213 
214 bool Derivative::init(UINT derivativeOrder,Float delta,UINT numDimensions,bool filterData,UINT filterSize){
215 
216  initialized = false;
217 
218  if( derivativeOrder != FIRST_DERIVATIVE && derivativeOrder != SECOND_DERIVATIVE ){
219  errorLog << "init(UINT derivativeOrder,Float delta,UINT numDimensions,bool filterData,UINT filterSize) - Unknown derivativeOrder!" << std::endl;
220  return false;
221  }
222 
223  if( numDimensions == 0 ){
224  errorLog << "init(UINT derivativeOrder,Float delta,UINT numDimensions,bool filterData,UINT filterSize) - NumDimensions must be greater than 0!" << std::endl;
225  return false;
226  }
227 
228  if( delta <= 0 ){
229  errorLog << "init(UINT derivativeOrder,Float delta,UINT numDimensions,bool filterData,UINT filterSize) - Delta must be greater than 0!" << std::endl;
230  return false;
231  }
232 
233  if( filterSize == 0 ){
234  errorLog << "init(UINT derivativeOrder,Float delta,UINT numDimensions,bool filterData,UINT filterSize) - FilterSize must be greater than zero!" << std::endl;
235  return false;
236  }
237 
238  this->derivativeOrder = derivativeOrder;
239  this->delta = delta;
240  this->numInputDimensions = numDimensions;
241  this->numOutputDimensions = numDimensions;
242  this->filterData = filterData;
243  this->filterSize = filterSize;
244  filter.init(filterSize, numDimensions);
245  yy.clear();
246  yy.resize(numDimensions,0);
247  yyy.clear();
248  yyy.resize(numDimensions,0);
249  processedData.clear();
250  processedData.resize(numDimensions,0);
251  initialized = true;
252  return true;
253 }
254 
255 Float Derivative::computeDerivative(const Float x){
256 
257  if( numInputDimensions != 1 ){
258  errorLog << "computeDerivative(const Float x) - The Number Of Input Dimensions is not 1! NumInputDimensions: " << numInputDimensions << std::endl;
259  return 0;
260  }
261 
263 
264  if( y.size() == 0 ) return 0 ;
265 
266  return y[0];
267 }
268 
270 
271  if( !initialized ){
272  errorLog << "computeDerivative(const VectorFloat &x) - Not Initialized!" << std::endl;
273  return VectorFloat();
274  }
275 
276  if( x.size() != numInputDimensions ){
277  errorLog << "computeDerivative(const VectorFloat &x) - The Number Of Input Dimensions (" << numInputDimensions << ") does not match the size of the input vector (" << x.size() << ")!" << std::endl;
278  return VectorFloat();
279  }
280 
281  VectorFloat y;
282  if( filterData ){
283  y = filter.filter( x );
284  }else y = x;
285 
286  for(UINT n=0; n<numInputDimensions; n++){
287  processedData[n] = (y[n]-yy[n])/delta;
288  yy[n] = y[n];
289  }
290 
291  if( derivativeOrder == SECOND_DERIVATIVE ){
292  Float tmp = 0;
293  for(UINT n=0; n<numInputDimensions; n++){
294  tmp = processedData[n];
295  processedData[n] = (processedData[n]-yyy[n])/delta;
296  yyy[n] = tmp;
297  }
298  }
299 
300  return processedData;
301 }
302 
303 bool Derivative::setDerivativeOrder(UINT derivativeOrder){
304  if( derivativeOrder == FIRST_DERIVATIVE || derivativeOrder == SECOND_DERIVATIVE ){
305  this->derivativeOrder = derivativeOrder;
306  if( initialized ) init(derivativeOrder, delta, numInputDimensions,filterData,filterSize);
307  return true;
308  }
309  errorLog << "setDerivativeOrder(UINT derivativeOrder) - Unkown derivativeOrder" << std::endl;
310  return false;
311 }
312 
313 bool Derivative::setFilterSize(UINT filterSize){
314  if( filterSize > 0 ){
315  this->filterSize = filterSize;
316  if( initialized ) init(derivativeOrder, delta, numInputDimensions,filterData,filterSize);
317  return true;
318  }
319  errorLog << "setFilterSize(UINT filterSize) - FilterSize must be greater than zero!" << std::endl;
320  return false;
321 }
322 
323 bool Derivative::enableFiltering(bool filterData){
324  this->filterData = filterData;
325  if( initialized ) init(derivativeOrder, delta, numInputDimensions,filterData,filterSize);
326  return true;
327 }
328 
329 Float Derivative::getDerivative(UINT derivativeOrder){
330 
331  switch( derivativeOrder ){
332  case 0:
333  return processedData[0];
334  break;
335  case( FIRST_DERIVATIVE ):
336  return yy[0];
337  break;
338  case( SECOND_DERIVATIVE ):
339  return yyy[0];
340  break;
341  default:
342  warningLog << "getDerivative(UINT derivativeOrder) - Unkown derivativeOrder: " << derivativeOrder << std::endl;
343  break;
344  }
345 
346  return 0;
347 }
348 
350 
351  switch( derivativeOrder ){
352  case 0:
353  return processedData;
354  break;
355  case( FIRST_DERIVATIVE ):
356  return yy;
357  break;
358  case( SECOND_DERIVATIVE ):
359  return yyy;
360  break;
361  default:
362  warningLog << "getDerivative(UINT derivativeOrder) - Unkown derivativeOrder: " << derivativeOrder << std::endl;
363  break;
364  }
365 
366  return VectorFloat();
367 }
368 
369 GRT_END_NAMESPACE
virtual bool save(std::fstream &file) const
Definition: Derivative.cpp:126
bool init(UINT filterSize, UINT numDimensions)
UINT filterSize
The size of the filter used to filter the input data before the derivative is computed.
Definition: Derivative.h:225
virtual bool resize(const unsigned int size)
Definition: Vector.h:133
bool setDerivativeOrder(UINT derivativeOrder)
Definition: Derivative.cpp:303
VectorFloat yy
A buffer holding the previous input value(s)
Definition: Derivative.h:229
UINT getSize() const
Definition: Vector.h:191
VectorFloat yyy
A buffer holding the previous first derivative values.
Definition: Derivative.h:230
Float computeDerivative(const Float x)
Definition: Derivative.cpp:255
virtual bool load(std::fstream &file)
Definition: Derivative.cpp:145
VectorFloat getDerivatives(UINT derivativeOrder=FIRST_DERIVATIVE)
Definition: Derivative.cpp:349
virtual bool reset()
Definition: Derivative.cpp:121
Derivative & operator=(const Derivative &rhs)
Definition: Derivative.cpp:63
Float filter(const Float x)
Float getDerivative(UINT derivativeOrder=FIRST_DERIVATIVE)
Definition: Derivative.cpp:329
std::string getPreProcessingType() const
virtual bool process(const VectorFloat &inputVector)
Definition: Derivative.cpp:103
bool filterData
Flags if the input data should be filtered before the derivative is computed.
Definition: Derivative.h:227
Float delta
The estimated time between sensor samples.
Definition: Derivative.h:226
bool copyBaseVariables(const PreProcessing *preProcessingModule)
virtual ~Derivative()
Definition: Derivative.cpp:59
bool enableFiltering(bool filterData)
Definition: Derivative.cpp:323
UINT derivativeOrder
The order of the derivative that will be computed (either FIRST_DERIVATIVE or SECOND_DERIVATIVE) ...
Definition: Derivative.h:224
Derivative(UINT derivativeOrder=FIRST_DERIVATIVE, Float delta=1, UINT numDimensions=1, bool filterData=true, UINT filterSize=3)
Definition: Derivative.cpp:29
bool setFilterSize(UINT filterSize)
Definition: Derivative.cpp:313
virtual bool deepCopyFrom(const PreProcessing *preProcessing)
Definition: Derivative.cpp:77
The Derivative class computes either the first or second order derivative of the input signal...
MovingAverageFilter filter
The filter used to low pass filter the input data.
Definition: Derivative.h:228