GestureRecognitionToolkit  Version: 0.1.0
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
TimeSeriesClassificationSampleTrimmer.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 
22 
23 GRT_BEGIN_NAMESPACE
24 
26  this->trimThreshold = trimThreshold;
27  this->maximumTrimPercentage = maximumTrimPercentage;
28  debugLog.setProceedingText("[DEBUG TimeSeriesTrimmer]");
29  warningLog.setProceedingText("[WARNING TimeSeriesTrimmer]");
30  errorLog.setProceedingText("[ERROR TimeSeriesTrimmer]");
31 }
32 
34 
36 
37  const UINT M = timeSeries.getLength();
38  const UINT N = timeSeries.getNumDimensions();
39 
40  if( M == 0 ){
41  warningLog << "trimTimeSeries(TimeSeriesClassificationSample &timeSeries) - can't trim data, the length of the input time series is 0!" << std::endl;
42  return false;
43  }
44 
45  if( N == 0 ){
46  warningLog << "trimTimeSeries(TimeSeriesClassificationSample &timeSeries) - can't trim data, the number of dimensions in the input time series is 0!" << std::endl;
47  return false;
48  }
49 
50  //Compute the energy of the time series
51  Float maxValue = 0;
52  VectorDouble x(M,0);
53 
54  for(UINT i=1; i<M; i++){
55  for(UINT j=0; j<N; j++){
56  x[i] += fabs(timeSeries[i][j]-timeSeries[i-1][j]);
57  }
58  x[i] /= N;
59  if( x[i] > maxValue ) maxValue = x[i];
60  }
61 
62  //Normalize x so that the maximum energy has a value of 1
63  //At the same time search for the first time x[i] passes the trim threshold
64  UINT firstIndex = 0;
65  for(UINT i=1; i<M; i++){
66  x[i] /= maxValue;
67 
68  if( x[i] > trimThreshold && firstIndex == 0 ){
69  firstIndex = i;
70  }
71  }
72 
73  //Search for the last time x[i] passes the trim threshold
74  UINT lastIndex = 0;
75  for(UINT i=M-1; i>firstIndex; i--){
76  if( x[i] > trimThreshold && lastIndex == 0 ){
77  lastIndex = i;
78  break;
79  }
80  }
81 
82  if( firstIndex == 0 && lastIndex == 0 ){
83  warningLog << "Failed to find either the first index or the last index!" << std::endl;
84  return false;
85  }
86 
87  if( firstIndex == lastIndex ){
88  warningLog << "The first index and last index are the same!" << std::endl;
89  return false;
90  }
91 
92  if( firstIndex > lastIndex ){
93  warningLog << "The first index is greater than the last index!" << std::endl;
94  return false;
95  }
96 
97  if( lastIndex == 0 ){
98  warningLog << "Failed to find the last index!" << std::endl;
99  lastIndex = M-1;
100  }
101 
102  //Compute how long the new time series would be if we trimmed it
103  UINT newM = lastIndex-firstIndex;
104  Float trimPercentage = (Float(newM) / Float(M)) * 100.0;
105 
106  if( 100 - trimPercentage <= maximumTrimPercentage ){
107 
108  MatrixDouble newTimeSeries(newM,N);
109  UINT index = 0;
110  for(UINT i=firstIndex; i<lastIndex; i++){
111  for(UINT j=0; j<N; j++){
112  newTimeSeries[index][j] = timeSeries[i][j];
113  }
114  index++;
115  }
116 
117  timeSeries.setTrainingSample(timeSeries.getClassLabel(), newTimeSeries);
118  return true;
119  }
120 
121  warningLog << "Maximum Trim Percentage Excedded, Can't Trim Sample!";
122  warningLog << " Original Timeseries Length: " << M << " Trimmed Timeseries Length: " << newM;
123  warningLog << " Percentage: " << (100-trimPercentage) << " MaximumTrimPercentage: " << maximumTrimPercentage << std::endl;
124  return false;
125 }
126 
127 GRT_END_NAMESPACE
128 
TimeSeriesClassificationSampleTrimmer(Float trimThreshold=0.1, Float maximumTrimPercentage=80)
This class provides a useful tool to automatically trim timeseries data.
bool trimTimeSeries(TimeSeriesClassificationSample &timeSeries)