GestureRecognitionToolkit  Version: 0.2.5
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
ContinuousHiddenMarkovModel.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 #include "HMMEnums.h"
24 
25 GRT_BEGIN_NAMESPACE
26 
27 //Init the model with a set number of states and symbols
28 ContinuousHiddenMarkovModel::ContinuousHiddenMarkovModel(const UINT downsampleFactor,const UINT delta,const bool autoEstimateSigma,const Float sigma) : MLBase( "ContinuousHiddenMarkovModel" )
29 {
30 
31  clear();
32  this->downsampleFactor = downsampleFactor;
33  this->delta = delta;
34  this->autoEstimateSigma = autoEstimateSigma;
35  this->sigma = sigma;
36  modelType = HMMModelTypes::HMM_LEFTRIGHT;
37  cThreshold = 0;
38  useScaling = false;
39 }
40 
41 ContinuousHiddenMarkovModel::ContinuousHiddenMarkovModel(const ContinuousHiddenMarkovModel &rhs) : MLBase( "ContinuousHiddenMarkovModel" )
42 {
43  this->downsampleFactor = rhs.downsampleFactor;
44  this->numStates = rhs.numStates;
45  this->classLabel = rhs.classLabel;
46  this->timeseriesLength = rhs.timeseriesLength;
47  this->sigma = rhs.sigma;
48  this->autoEstimateSigma = rhs.autoEstimateSigma;
49  this->sigmaStates = rhs.sigmaStates;
50  this->a = rhs.a;
51  this->b = rhs.b;
52  this->pi = rhs.pi;
53  this->alpha = rhs.alpha;
54  this->c = rhs.c;
55  this->observationSequence = rhs.observationSequence;
56  this->obsSequence = rhs.obsSequence;
57  this->estimatedStates = rhs.estimatedStates;
58  this->modelType = rhs.modelType;
59  this->delta = rhs.delta;
60  this->loglikelihood = rhs.loglikelihood;
61  this->cThreshold = rhs.cThreshold;
62 }
63 
64 //Default destructor
65 ContinuousHiddenMarkovModel::~ContinuousHiddenMarkovModel(){
66 
67 }
68 
69 ContinuousHiddenMarkovModel& ContinuousHiddenMarkovModel::operator=(const ContinuousHiddenMarkovModel &rhs){
70 
71  if( this != &rhs ){
72  this->downsampleFactor = rhs.downsampleFactor;
73  this->numStates = rhs.numStates;
74  this->classLabel = rhs.classLabel;
75  this->timeseriesLength = rhs.timeseriesLength;
76  this->sigma = rhs.sigma;
77  this->autoEstimateSigma = rhs.autoEstimateSigma;
78  this->sigmaStates = rhs.sigmaStates;
79  this->a = rhs.a;
80  this->b = rhs.b;
81  this->pi = rhs.pi;
82  this->alpha = rhs.alpha;
83  this->c = rhs.c;
84  this->observationSequence = rhs.observationSequence;
85  this->obsSequence = rhs.obsSequence;
86  this->estimatedStates = rhs.estimatedStates;
87  this->modelType = rhs.modelType;
88  this->delta = rhs.delta;
89  this->loglikelihood = rhs.loglikelihood;
90  this->cThreshold = rhs.cThreshold;
91 
92  const MLBase *basePointer = &rhs;
93  this->copyMLBaseVariables( basePointer );
94  }
95 
96  return *this;
97 }
98 
100 
101  if( !trained ){
102  errorLog << "predict_(VectorFloat &x) - The model is not trained!" << std::endl;
103  return false;
104  }
105 
106  if( x.getSize() != numInputDimensions ){
107  errorLog << "predict_(VectorFloat &x) - The input vector size (" << x.getSize() << ") does not match the number of input dimensions (" << numInputDimensions << ")" << std::endl;
108  return false;
109  }
110 
111  //Add the new sample to the circular buffer
112  observationSequence.push_back( x );
113 
114  //Convert the circular buffer to MatrixFloat
115  for(unsigned int i=0; i<observationSequence.getSize(); i++){
116  for(unsigned int j=0; j<numInputDimensions; j++){
117  obsSequence[i][j] = observationSequence[i][j];
118  }
119  }
120 
121  return predict_( obsSequence );
122 }
123 
125 
126  if( !trained ){
127  errorLog << "predict_( MatrixFloat &timeseries ) - The model is not trained!" << std::endl;
128  return false;
129  }
130 
131  if( timeseries.getNumCols() != numInputDimensions ){
132  errorLog << "predict_( MatrixFloat &timeseries ) - The matrix column size (" << timeseries.getNumCols() << ") does not match the number of input dimensions (" << numInputDimensions << ")" << std::endl;
133  return false;
134  }
135 
136  unsigned int t,i,j,k,index = 0;
137  Float maxAlpha = 0;
138  Float norm = 0;
139 
140  //Downsample the observation timeseries using the same downsample factor of the training data
141  const unsigned int timeseriesLength = (unsigned int)timeseries.getNumRows();
142  const unsigned int T = downsampleFactor < timeseriesLength ? (unsigned int)floor( timeseriesLength / Float(downsampleFactor) ) : timeseriesLength;
143  const unsigned int K = downsampleFactor < timeseriesLength ? downsampleFactor : 1; //K is used to average over multiple bins
144  MatrixFloat obs(T,numInputDimensions);
145  for(j=0; j<numInputDimensions; j++){
146  index = 0;
147  for(i=0; i<T; i++){
148  norm = 0;
149  obs[i][j] = 0;
150  for(k=0; k<K; k++){
151  if( index < timeseriesLength ){
152  obs[i][j] += timeseries[index++][j];
153  norm += 1;
154  }
155  }
156  if( norm > 1 )
157  obs[i][j] /= norm;
158  }
159  }
160 
161  //Resize alpha, c, and the estimated states vector as needed
162  if( alpha.getNumRows() != T || alpha.getNumCols() != numStates ) alpha.resize(T,numStates);
163  if( (unsigned int)c.size() != T ) c.resize(T);
164  if( (unsigned int)estimatedStates.size() != T ) estimatedStates.resize(T);
165 
167  //Step 1: Init at t=0
168  t = 0;
169  c[t] = 0;
170  maxAlpha = 0;
171  for(i=0; i<numStates; i++){
172  alpha[t][i] = pi[i]*gauss(b,obs,sigmaStates,i,t,numInputDimensions);
173  c[t] += alpha[t][i];
174 
175  //Keep track of the best state at time t
176  if( alpha[t][i] > maxAlpha ){
177  maxAlpha = alpha[t][i];
178  estimatedStates[t] = i;
179  }
180  }
181 
182  //Set the inital scaling coeff
183  c[t] = 1.0/c[t];
184 
185  //Scale alpha
186  for(i=0; i<numStates; i++) alpha[t][i] *= c[t];
187 
188  //Step 2: Induction
189  for(t=1; t<T; t++){
190  c[t] = 0.0;
191  maxAlpha = 0;
192  for(j=0; j<numStates; j++){
193  alpha[t][j] = 0.0;
194  for(i=0; i<numStates; i++){
195  alpha[t][j] += alpha[t-1][i] * a[i][j];
196  }
197  alpha[t][j] *= gauss(b,obs,sigmaStates,j,t,numInputDimensions);
198  c[t] += alpha[t][j];
199 
200  //Keep track of the best state at time t
201  if( alpha[t][j] > maxAlpha ){
202  maxAlpha = alpha[t][j];
203  estimatedStates[t] = j;
204  }
205  }
206 
207  //Set the scaling coeff
208  c[t] = 1.0/c[t];
209 
210  //Scale Alpha
211  for(j=0; j<numStates; j++) alpha[t][j] *= c[t];
212  }
213 
214  //Termination
215  loglikelihood = 0.0;
216  for(t=0; t<T; t++) loglikelihood += log( c[t] );
217  loglikelihood = -loglikelihood; //Store the negative log likelihood
218 
219  //Set the phase as the last estimated state, this will give a phase between [0 1]
220  phase = (estimatedStates[T-1]+1.0)/Float(numStates);
221 
222  return true;
223 }
224 
225 bool ContinuousHiddenMarkovModel::train_(TimeSeriesClassificationSample &trainingData){
226 
227  //Clear any previous models
228  clear();
229 
230  //The number of states is simply set as the number of samples in the training sample
231  timeseriesLength = trainingData.getLength();
232  numStates = (unsigned int)floor((double)(timeseriesLength/downsampleFactor));
233  numInputDimensions = trainingData.getNumDimensions();
234  classLabel = trainingData.getClassLabel();
235 
236  //a is simply set as the number of 1/numStates
237  a.resize(numStates, numStates);
238  for(unsigned int i=0; i<numStates; i++){
239  for(unsigned int j=0; j<numStates; j++){
240  a[i][j] = 1.0/numStates;
241  }
242  }
243 
244  //b is simply set as the downsampled training sample
245  b.resize(numStates, numInputDimensions);
246 
247  unsigned int index = 0;
248  Float norm = 0;
249  for(unsigned int j=0; j<numInputDimensions; j++){
250  index = 0;
251  for(unsigned int i=0; i<numStates; i++){
252  norm = 0;
253  b[i][j] = 0;
254  for(unsigned int k=0; k<downsampleFactor; k++){
255  if( index < trainingData.getLength() ){
256  b[i][j] += trainingData[index++][j];
257  norm += 1;
258  }
259  }
260  if( norm > 1 )
261  b[i][j] /= norm;
262  }
263  }
264 
265  //Estimate pi
266  pi.resize(numStates);
267 
268  switch( modelType ){
269  case(HMM_ERGODIC):
270  for(UINT i=0; i<numStates; i++){
271  pi[i] = 1.0/numStates;
272  }
273  break;
274  case(HMM_LEFTRIGHT):
275  //Set the state transitions constraints
276  for(UINT i=0; i<numStates; i++){
277  norm = 0;
278  for(UINT j=0; j<numStates; j++){
279  if((j<i) || (j>i+delta)) a[i][j] = 0.0;
280  norm += a[i][j];
281  }
282  if( norm > 0 ){
283  for(UINT j=0; j<numStates; j++){
284  a[i][j] /= norm;
285  }
286  }
287  }
288 
289  //Set pi to start in state 0
290  for(UINT i=0; i<numStates; i++){
291  pi[i] = i==0 ? 1 : 0;
292  }
293  break;
294  default:
295  throw("HMM_ERROR: Unkown model type!");
296  return false;
297  break;
298  }
299 
300  //Setup sigma for each state
301  sigmaStates.resize( numStates, numInputDimensions );
302 
303  if( autoEstimateSigma ){
304 
305  //Estimate the standard dev for each dimension, for each state
306  MatrixFloat meanResults( numStates, numInputDimensions );
307  for(unsigned int j=0; j<numInputDimensions; j++){
308 
309  //Estimate the mean for each state
310  index = 0;
311  for(unsigned int i=0; i<numStates; i++){
312  norm = 0;
313  meanResults[i][j] = 0;
314  for(unsigned int k=0; k<downsampleFactor; k++){
315  if( index < trainingData.getLength() ){
316  meanResults[i][j] += trainingData[index++][j];
317  norm += 1;
318  }
319  }
320  if( norm > 1 ){
321  meanResults[i][j] /= norm;
322  }
323  }
324 
325  //Loop back over the data again and estimate the stddev for each state
326  index = 0;
327  for(unsigned int i=0; i<numStates; i++){
328  norm = 0;
329  sigmaStates[i][j] = 0;
330  for(unsigned int k=0; k<downsampleFactor; k++){
331  if( index < trainingData.getLength() ){
332  sigmaStates[i][j] += SQR( trainingData[index++][j]-meanResults[i][j] );
333  norm += 1;
334  }
335  }
336  if( norm > 1 ){
337  sigmaStates[i][j] = sqrt( 1.0/norm * sigmaStates[i][j] );
338  }
339 
340  if( sigmaStates[i][j] < sigma ){
341  sigmaStates[i][j] = sigma;
342  }
343  }
344  }
345 
346  }else{
347  sigmaStates.setAllValues(sigma);
348  }
349 
350  //Setup the observation buffer for prediction
351  observationSequence.resize( timeseriesLength, VectorFloat(numInputDimensions,0) );
352  obsSequence.resize(timeseriesLength,numInputDimensions);
353  estimatedStates.resize( numStates );
354 
355  //Finally, flag that the model was trained
356  trained = true;
357 
358  return true;
359 }
360 
362 
363  //Reset the base class
364  MLBase::reset();
365 
366  if( trained ){
367  for(unsigned int i=0; i<observationSequence.getSize(); i++){
368  observationSequence.push_back( VectorFloat(numInputDimensions,0) );
369  }
370  }
371 
372  return true;
373 }
374 
376 
377  //Clear the base class
378  MLBase::clear();
379 
380  numStates = 0;
381  loglikelihood = 0;
382  timeseriesLength = 0;
383  a.clear();
384  b.clear();
385  pi.clear();
386  alpha.clear();
387  c.clear();
388  observationSequence.clear();
389  obsSequence.clear();
390  estimatedStates.clear();
391  sigmaStates.clear();
392 
393  return true;
394 }
395 
397 
398  if( trained ){
399  trainingLog << "A: " << std::endl;
400  for(UINT i=0; i<a.getNumRows(); i++){
401  for(UINT j=0; j<a.getNumCols(); j++){
402  trainingLog << a[i][j] << "\t";
403  }
404  trainingLog << std::endl;
405  }
406 
407  trainingLog << "B: " << std::endl;
408  for(UINT i=0; i<b.getNumRows(); i++){
409  for(UINT j=0; j<b.getNumCols(); j++){
410  trainingLog << b[i][j] << "\t";
411  }
412  trainingLog << std::endl;
413  }
414 
415  trainingLog << "Pi: ";
416  for(size_t i=0; i<pi.size(); i++){
417  trainingLog << pi[i] << "\t";
418  }
419  trainingLog << std::endl;
420 
421  trainingLog << "SigmaStates: ";
422  for(UINT i=0; i<sigmaStates.getNumRows(); i++){
423  for(UINT j=0; j<sigmaStates.getNumCols(); j++){
424  trainingLog << sigmaStates[i][j] << "\t";
425  }
426  trainingLog << std::endl;
427  }
428  trainingLog << std::endl;
429 
430  //Check the weights all sum to 1
431  if( true ){
432  Float sum=0.0;
433  for(UINT i=0; i<a.getNumRows(); i++){
434  sum=0.0;
435  for(UINT j=0; j<a.getNumCols(); j++) sum += a[i][j];
436  if( sum <= 0.99 || sum >= 1.01 ) warningLog << "WARNING: A Row " << i <<" Sum: "<< sum << std::endl;
437  }
438  }
439  }
440 
441  return true;
442 
443 }
444 
445 bool ContinuousHiddenMarkovModel::setDownsampleFactor(const UINT downsampleFactor){
446  if( downsampleFactor > 0 ){
447  clear();
448  this->downsampleFactor = downsampleFactor;
449  return true;
450  }
451  warningLog << "setDownsampleFactor(const UINT downsampleFactor) - Failed to set downsample factor, it must be greater than zero!" << std::endl;
452  return false;
453 }
454 
455 bool ContinuousHiddenMarkovModel::setModelType(const UINT modelType){
456  if( modelType == HMM_ERGODIC || modelType == HMM_LEFTRIGHT ){
457  clear();
458  this->modelType = modelType;
459  return true;
460  }
461  warningLog << "setModelType(const UINT modelType) - Failed to set model type, unknown type!" << std::endl;
462  return false;
463 }
464 
466  if( delta > 0 ){
467  clear();
468  this->delta = delta;
469  return true;
470  }
471  warningLog << "setDelta(const UINT delta) - Failed to set delta, it must be greater than zero!" << std::endl;
472  return false;
473 }
474 
475 bool ContinuousHiddenMarkovModel::setSigma(const Float sigma){
476  if( sigma > 0 ){
477  this->sigma = sigma;
478 
479  if( !autoEstimateSigma && trained ){
480  sigmaStates.setAllValues(sigma);
481  }
482  return true;
483  }
484  warningLog << "setSigma(const Float sigma) - Failed to set sigma, it must be greater than zero!" << std::endl;
485  return false;
486 }
487 
488 bool ContinuousHiddenMarkovModel::setAutoEstimateSigma(const bool autoEstimateSigma){
489 
490  clear();
491 
492  this->autoEstimateSigma = autoEstimateSigma;
493 
494  return true;
495 }
496 
497 Float ContinuousHiddenMarkovModel::gauss( const MatrixFloat &x, const MatrixFloat &y, const MatrixFloat &sigma, const unsigned int i,const unsigned int j,const unsigned int N ){
498  Float z = 1;
499  for(unsigned int n=0; n<N; n++){
500  z *= (1.0/( sigma[i][n] * SQRT_TWO_PI )) * exp( - SQR(x[i][n]-y[j][n])/(2.0*SQR(sigma[i][n])) );
501  }
502  return z;
503 }
504 
505 bool ContinuousHiddenMarkovModel::save( std::fstream &file ) const{
506 
507  if(!file.is_open())
508  {
509  errorLog << "save( fstream &file ) - File is not open!" << std::endl;
510  return false;
511  }
512 
513  //Write the header info
514  file << "CONTINUOUS_HMM_MODEL_FILE_V1.0\n";
515 
516  //Write the base settings to the file
517  if( !MLBase::saveBaseSettingsToFile(file) ){
518  errorLog <<"save(fstream &file) - Failed to save classifier base settings to file!" << std::endl;
519  return false;
520  }
521 
522  file << "DownsampleFactor: " << downsampleFactor << std::endl;
523  file << "NumStates: " << numStates << std::endl;
524  file << "ClassLabel: " << classLabel << std::endl;
525  file << "TimeseriesLength: " << timeseriesLength << std::endl;
526  file << "Sigma: " << sigma << std::endl;
527  file << "AutoEstimateSigma: " << autoEstimateSigma << std::endl;
528  file << "ModelType: " << modelType << std::endl;
529  file << "Delta: " << delta << std::endl;
530  file << "Threshold: " << cThreshold << std::endl;
531 
532  if( trained ){
533  file << "A:\n";
534  for(UINT i=0; i<numStates; i++){
535  for(UINT j=0; j<numStates; j++){
536  file << a[i][j];
537  if( j+1 < numStates ) file << "\t";
538  }file << std::endl;
539  }
540 
541  file << "B:\n";
542  for(UINT i=0; i<numStates; i++){
543  for(UINT j=0; j<numInputDimensions; j++){
544  file << b[i][j];
545  if( j+1 < numInputDimensions ) file << "\t";
546  }file << std::endl;
547  }
548 
549  file<<"Pi: ";
550  for(UINT i=0; i<numStates; i++){
551  file << pi[i];
552  if( i+1 < numStates ) file << "\t";
553  }
554  file << std::endl;
555 
556  file << "SigmaStates: ";
557  for(UINT i=0; i<numStates; i++){
558  for(UINT j=0; j<numInputDimensions; j++){
559  file << sigmaStates[i][j];
560  if( j+1 < numInputDimensions ) file << "\t";
561  }file << std::endl;
562  }
563  file << std::endl;
564 
565  }
566 
567  return true;
568 }
569 
570 bool ContinuousHiddenMarkovModel::load( std::fstream &file ){
571 
572  clear();
573 
574  if(!file.is_open())
575  {
576  errorLog << "load( fstream &file ) - File is not open!" << std::endl;
577  return false;
578  }
579 
580  std::string word;
581 
582  file >> word;
583 
584  //Find the file type header
585  if(word != "CONTINUOUS_HMM_MODEL_FILE_V1.0"){
586  errorLog << "load( fstream &file ) - Could not find Model File Header!" << std::endl;
587  return false;
588  }
589 
590  //Load the base settings from the file
592  errorLog << "load(string filename) - Failed to load base settings from file!" << std::endl;
593  return false;
594  }
595 
596  file >> word;
597  if(word != "DownsampleFactor:"){
598  errorLog << "load( fstream &file ) - Could not find the DownsampleFactor header." << std::endl;
599  return false;
600  }
601  file >> downsampleFactor;
602 
603  file >> word;
604  if(word != "NumStates:"){
605  errorLog << "load( fstream &file ) - Could not find the NumStates header." << std::endl;
606  return false;
607  }
608  file >> numStates;
609 
610  file >> word;
611  if(word != "ClassLabel:"){
612  errorLog << "load( fstream &file ) - Could not find the ClassLabel header." << std::endl;
613  return false;
614  }
615  file >> classLabel;
616 
617  file >> word;
618  if(word != "TimeseriesLength:"){
619  errorLog << "load( fstream &file ) - Could not find the TimeseriesLength header." << std::endl;
620  return false;
621  }
622  file >> timeseriesLength;
623 
624  file >> word;
625  if(word != "Sigma:"){
626  errorLog << "load( fstream &file ) - Could not find the Sigma for the header." << std::endl;
627  return false;
628  }
629  file >> sigma;
630 
631  file >> word;
632  if(word != "AutoEstimateSigma:"){
633  errorLog << "load( fstream &file ) - Could not find the AutoEstimateSigma for the header." << std::endl;
634  return false;
635  }
636  file >> autoEstimateSigma;
637 
638  file >> word;
639  if(word != "ModelType:"){
640  errorLog << "load( fstream &file ) - Could not find the ModelType for the header." << std::endl;
641  return false;
642  }
643  file >> modelType;
644 
645  file >> word;
646  if(word != "Delta:"){
647  errorLog << "load( fstream &file ) - Could not find the Delta for the header." << std::endl;
648  return false;
649  }
650  file >> delta;
651 
652  file >> word;
653  if(word != "Threshold:"){
654  errorLog << "load( fstream &file ) - Could not find the Threshold for the header." << std::endl;
655  return false;
656  }
657  file >> cThreshold;
658 
659  if( trained ){
660  a.resize(numStates,numStates);
661  b.resize(numStates,numInputDimensions);
662  pi.resize(numStates);
663  sigmaStates.resize(numStates,numInputDimensions);
664 
665  //Load the A, B and Pi matrices
666  file >> word;
667  if(word != "A:"){
668  errorLog << "load( fstream &file ) - Could not find the A matrix header." << std::endl;
669  return false;
670  }
671 
672  //Load A
673  for(UINT i=0; i<numStates; i++){
674  for(UINT j=0; j<numStates; j++){
675  file >> a[i][j];
676  }
677  }
678 
679  file >> word;
680  if(word != "B:"){
681  errorLog << "load( fstream &file ) - Could not find the B matrix header." << std::endl;
682  return false;
683  }
684 
685  //Load B
686  for(UINT i=0; i<numStates; i++){
687  for(UINT j=0; j<numInputDimensions; j++){
688  file >> b[i][j];
689  }
690  }
691 
692  file >> word;
693  if(word != "Pi:"){
694  errorLog << "load( fstream &file ) - Could not find the Pi header." << std::endl;
695  return false;
696  }
697 
698  //Load Pi
699  for(UINT i=0; i<numStates; i++){
700  file >> pi[i];
701  }
702 
703  file >> word;
704  if(word != "SigmaStates:"){
705  errorLog << "load( fstream &file ) - Could not find the SigmaStates header." << std::endl;
706  return false;
707  }
708 
709  //Load sigmaStates
710  for(UINT i=0; i<numStates; i++){
711  for(UINT j=0; j<numInputDimensions; j++){
712  file >> sigmaStates[i][j];
713  }
714  }
715 
716  //Setup the observation buffer for prediction
717  observationSequence.resize( timeseriesLength, VectorFloat(numInputDimensions,0) );
718  obsSequence.resize(timeseriesLength,numInputDimensions);
719  estimatedStates.resize( numStates );
720  }
721 
722  return true;
723 }
724 
725 GRT_END_NAMESPACE
bool saveBaseSettingsToFile(std::fstream &file) const
Definition: MLBase.cpp:435
virtual bool load(std::fstream &file) override
virtual bool save(std::fstream &file) const override
virtual bool predict_(VectorFloat &inputVector)
Definition: MLBase.cpp:137
Vector< UINT > estimatedStates
The estimated states for prediction.
virtual bool reset()
Definition: MLBase.cpp:147
Float cThreshold
The classification threshold for this model.
This class acts as the main interface for using a Hidden Markov Model.
MatrixFloat a
The transitions probability matrix.
Float loglikelihood
The log likelihood of an observation sequence given the modal, calculated by the forward method...
UINT getSize() const
Definition: Vector.h:201
VectorFloat pi
The state start probability vector.
UINT modelType
The model type (LEFTRIGHT, or ERGODIC)
virtual bool predict_(VectorFloat &x) override
UINT delta
The number of states a model can move to in a LEFTRIGHT model.
CircularBuffer< VectorFloat > observationSequence
A buffer to store data for realtime prediction.
bool copyMLBaseVariables(const MLBase *mlBase)
Definition: MLBase.cpp:62
This class implements a continuous Hidden Markov Model.
UINT classLabel
The class label associated with this model.
unsigned int getNumRows() const
Definition: Matrix.h:574
unsigned int getNumCols() const
Definition: Matrix.h:581
MatrixFloat sigmaStates
The sigma value for each state.
virtual bool print() const override
bool loadBaseSettingsFromFile(std::fstream &file)
Definition: MLBase.cpp:458
virtual bool clear()
Definition: MLBase.cpp:149
virtual bool resize(const unsigned int r, const unsigned int c)
Definition: Matrix.h:245
MatrixFloat b
The emissions probability matrix.
UINT timeseriesLength
The length of the training timeseries.
This is the main base class that all GRT machine learning algorithms should inherit from...
Definition: MLBase.h:72
bool setModelType(const UINT modelType)
UINT numStates
The number of states for this model.