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