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