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