Visual Servoing Platform  version 3.6.1 under development (2024-05-09)
tutorial-meandrift.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31 *****************************************************************************/
32 
34 
35 #include <cstring> //std::memcpy
36 
37 #include <visp3/core/vpConfig.h>
38 #include <visp3/core/vpGaussRand.h>
39 #include <visp3/core/vpStatisticalTestEWMA.h>
40 #include <visp3/core/vpStatisticalTestHinkley.h>
41 #include <visp3/core/vpStatisticalTestMeanAdjustedCUSUM.h>
42 #include <visp3/core/vpStatisticalTestShewhart.h>
43 #include <visp3/core/vpStatisticalTestSigma.h>
44 #include <visp3/gui/vpPlot.h>
45 
46 #if defined(VISP_HAVE_DISPLAY)
48 {
50 
54 typedef enum TypeTest
55 {
65 
72 std::string typeTestToString(const TypeTest &type)
73 {
74  std::string result;
75  switch (type) {
76  case HINLKEY_TYPE_TEST:
77  result = "hinkley";
78  break;
79  case EWMA_TYPE_TEST:
80  result = "ewma";
81  break;
83  result = "cusum";
84  break;
85  case SHEWHART_TYPE_TEST:
86  result = "shewhart";
87  break;
88  case SIGMA_TYPE_TEST:
89  result = "sigma";
90  break;
91  case UNKOWN_TYPE_TEST:
92  default:
93  result = "unknown-type-test";
94  break;
95  }
96  return result;
97 }
98 
106 TypeTest typeTestFromString(const std::string &name)
107 {
108  TypeTest result = UNKOWN_TYPE_TEST;
109  unsigned int count = static_cast<unsigned int>(COUNT_TYPE_TEST);
110  unsigned int id = 0;
111  bool hasNotFound = true;
112  while ((id < count) && hasNotFound) {
113  TypeTest temp = static_cast<TypeTest>(id);
114  if (typeTestToString(temp) == name) {
115  result = temp;
116  hasNotFound = false;
117  }
118  ++id;
119  }
120  return result;
121 }
122 
131 std::string getAvailableTypeTest(const std::string &prefix = "<", const std::string &sep = " , ",
132  const std::string &suffix = ">")
133 {
134  std::string msg(prefix);
135  unsigned int count = static_cast<unsigned int>(COUNT_TYPE_TEST);
136  unsigned int lastId = count - 1;
137  for (unsigned int i = 0; i < lastId; i++) {
138  msg += typeTestToString(static_cast<TypeTest>(i)) + sep;
139  }
140  msg += typeTestToString(static_cast<TypeTest>(lastId)) + suffix;
141  return msg;
142 }
143 
151 template <typename T>
152 std::string numberToString(const T &number)
153 {
154  std::stringstream ss;
155  ss << number;
156  return ss.str();
157 }
158 
165 std::string boolToString(const bool &boolean)
166 {
167  if (boolean) {
168  return "true";
169  }
170  else {
171  return "false";
172  }
173 }
174 
184 std::string wecoRulesToString(const bool rules[vpStatisticalTestShewhart::COUNT_WECO - 1], const std::string &prefix = "[", const std::string &suffix = "]", const std::string &sep = " , ")
185 {
186  std::string rulesAsString = prefix;
187  for (unsigned int i = 0; i < vpStatisticalTestShewhart::COUNT_WECO - 2; ++i) {
188  if (rules[i]) {
189  rulesAsString += "ON";
190  }
191  else {
192  rulesAsString += "OFF";
193  }
194  rulesAsString += sep;
195  }
196  if (rules[vpStatisticalTestShewhart::COUNT_WECO - 2]) {
197  rulesAsString += "ON";
198  }
199  else {
200  rulesAsString += "OFF";
201  }
202  rulesAsString += suffix;
203  return rulesAsString;
204 }
205 
209 const bool CONST_ALL_ALARM_OFF[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT] = { false, false, false, false };
210 
214 const bool CONST_ALL_ALARM_ON[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT] = { true, true, true, true };
215 
223 void vectorOfStringToMeanDriftTypeArray(const std::vector<std::string> &names, bool array[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT])
224 {
225  std::memcpy(array, CONST_ALL_ALARM_OFF, vpStatisticalTestAbstract::MEAN_DRIFT_COUNT * sizeof(bool));
226  size_t nbNames = names.size();
227  for (size_t i = 0; i < nbNames; ++i) {
229  std::cout << "alarm[" << names[i] << "] (i.e. " << static_cast<unsigned int>(alarmToActivate) << ") set to true" << std::endl;
230  array[static_cast<unsigned int>(alarmToActivate)] = true;
231  if (alarmToActivate == vpStatisticalTestAbstract::MEAN_DRIFT_BOTH) {
234  }
235  }
238  }
239 }
240 
249 {
250  std::vector<std::string> listActivatedAlarms;
251  unsigned int nbTypeTests = static_cast<unsigned int>(vpStatisticalTestAbstract::MEAN_DRIFT_COUNT);
252  for (unsigned int id = 0; id < nbTypeTests; ++id) {
253  if (array[id]) {
255  std::string testName = vpStatisticalTestAbstract::vpMeanDriftTypeToString(test);
256  listActivatedAlarms.push_back(testName);
257  }
258  }
259  return listActivatedAlarms;
260 }
261 
273  const std::string &prefix = "[", const std::string &sep = " , ",
274  const std::string &suffix = "]")
275 {
276  std::vector<std::string> listActivatedAlarms = meanDriftArrayToVectorOfString(array);
277  std::string result = prefix;
278  size_t nbTestActivated = listActivatedAlarms.size();
279  if (nbTestActivated == 0) {
280  return prefix + " " + suffix;
281  }
282  for (size_t i = 0; i < nbTestActivated - 1; ++i) {
283  result += listActivatedAlarms[i] + sep;
284  }
285  result += listActivatedAlarms[nbTestActivated - 1] + suffix;
286  return result;
287 }
288 
296 {
297  unsigned int nbActivated = 0;
298  unsigned int nbTypeAlarms = static_cast<unsigned int>(vpStatisticalTestAbstract::MEAN_DRIFT_COUNT);
299  for (unsigned int id = 0; id < nbTypeAlarms; ++id) {
300  if (array[id]) {
301  ++nbActivated;
302  }
303  }
304  return nbActivated;
305 }
306 
308 
311 typedef struct ParametersForAlgo
312 {
313  unsigned int m_test_nbsamples;
316  float m_cusum_h;
317  float m_cusum_k;
318  float m_ewma_alpha;
322  float m_hinkley_h;
323  float m_hinkley_k;
326  float m_sigma_h;
329  : m_test_nbsamples(30)
330  , m_cusum_h(4.76f)
331  , m_cusum_k(1.f)
332  , m_ewma_alpha(0.1f)
333  , m_hinkley_alpha(4.76f)
334  , m_hinkley_delta(1.f)
336  , m_hinkley_h(4.76f)
337  , m_hinkley_k(1.f)
338  , m_shewhart_useWECO(false)
339  , m_sigma_h(3.f)
340  {
345  }
348 }
349 
350 int testOnSynthetic(const TutorialMeanDrift::TypeTest &type, const TutorialMeanDrift::ParametersForAlgo parameters,
351  const float &mean, const float &mean_drift, const float &stdev)
352 {
353  const float dt = 10.f; // Emulate a 10ms period
354 
356  vpPlot plotter(1);
357  plotter.initGraph(0, 1);
358  plotter.setTitle(0, "Evolution of the signal");
359  plotter.setUnitX(0, "Frame ID");
360  plotter.setUnitY(0, "No units");
362 
364  unsigned int idFrame = 0;
365  vpStatisticalTestAbstract *p_test = nullptr;
366  switch (type) {
368  p_test = new vpStatisticalTestEWMA(parameters.m_ewma_alpha);
369  break;
371  p_test = new vpStatisticalTestHinkley(parameters.m_hinkley_alpha, parameters.m_hinkley_delta, parameters.m_test_nbsamples);
372  break;
374  p_test = new vpStatisticalTestMeanAdjustedCUSUM(parameters.m_cusum_h, parameters.m_cusum_k, parameters.m_test_nbsamples);
375  break;
377  p_test = new vpStatisticalTestShewhart(parameters.m_shewhart_useWECO, parameters.m_shewhart_rules, parameters.m_test_nbsamples);
378  break;
380  p_test = new vpStatisticalTestSigma(parameters.m_sigma_h, parameters.m_test_nbsamples);
381  break;
382  default:
383  throw(vpException(vpException::badValue, TutorialMeanDrift::typeTestToString(type) + " is not handled."));
384  break;
385  }
386 
388  // Initialization of Hinkley's test in automatic mode
389  delete p_test;
390  p_test = new vpStatisticalTestHinkley(parameters.m_hinkley_h, parameters.m_hinkley_k, true, parameters.m_test_nbsamples);
391  }
393 
394  float signal;
395 
397  // Initial computation of the mean and stdev of the input signal
398  for (unsigned int i = 0; i < parameters.m_test_nbsamples; ++i) {
399  vpGaussRand rndGen(stdev, mean, static_cast<long>(idFrame * dt));
400  signal = static_cast<float>(rndGen());
401  p_test->testDownUpwardMeanDrift(signal);
402  ++idFrame;
403  }
405 
406  std::cout << "Estimated mean of the input signal: " << p_test->getMean() << std::endl;
407  std::cout << "Estimated stdev of the input signal: " << p_test->getStdev() << std::endl;
408 
410  float mean_eff = mean;
411  bool hasToRun = true;
413  while (hasToRun) {
414  vpGaussRand rndGen(stdev, mean_eff, static_cast<long>(idFrame * dt));
415  signal = static_cast<float>(rndGen());
416  plotter.plot(0, 0, idFrame - parameters.m_test_nbsamples, signal);
417  drift_type = p_test->testDownUpwardMeanDrift(signal);
418  if ((drift_type != vpStatisticalTestAbstract::MEAN_DRIFT_NONE) && (parameters.m_test_activatedalarms[drift_type])) {
419  hasToRun = false;
420  }
421  else {
422  mean_eff += mean_drift;
423  ++idFrame;
424  }
425  }
427 
429  std::cout << "Test failed at frame: " << idFrame - parameters.m_test_nbsamples << std::endl;
430  std::cout << "Type of mean drift: " << vpStatisticalTestAbstract::vpMeanDriftTypeToString(drift_type) << std::endl;
431  std::cout << "Last signal value: " << signal << std::endl;
432  if (type == TutorialMeanDrift::EWMA_TYPE_TEST) {
433  vpStatisticalTestEWMA *p_testEwma = dynamic_cast<vpStatisticalTestEWMA *>(p_test);
434  std::cout << "\tw(t) = " << p_testEwma->getWt() << std::endl;
435  }
437  vpStatisticalTestMeanAdjustedCUSUM *p_testCusum = dynamic_cast<vpStatisticalTestMeanAdjustedCUSUM *>(p_test);
438  std::cout << "\tLower cusum = " << p_testCusum->getTestSignalMinus() << std::endl;
439  std::cout << "\tUpper cusum = " << p_testCusum->getTestSignalPlus() << std::endl;
440  }
441  else if (type==TutorialMeanDrift::SHEWHART_TYPE_TEST) {
442  vpStatisticalTestShewhart *p_testShewhart = dynamic_cast<vpStatisticalTestShewhart *>(p_test);
443  std::vector<float> signal = p_testShewhart->getSignals();
444  size_t nbSignal = signal.size();
445  std::cout << "Signal history = [ ";
446  for (size_t i = 0; i < nbSignal; ++i) {
447  std::cout << signal[i] << " ";
448  }
449  std::cout << "]" << std::endl;
450  std::cout << "\tWECO alarm type = " << vpStatisticalTestShewhart::vpWecoRulesAlarmToString(p_testShewhart->getAlarm()) << std::endl;
451  }
452  else if (type == TutorialMeanDrift::HINLKEY_TYPE_TEST) {
453  vpStatisticalTestHinkley *p_hinkley = dynamic_cast<vpStatisticalTestHinkley *>(p_test);
454  float Mk = p_hinkley->getMk();
455  float Nk = p_hinkley->getNk();
456  float Sk = p_hinkley->getSk();
457  float Tk = p_hinkley->getTk();
458  std::cout << "S+(t) = " << Tk - Nk <<std::endl;
459  std::cout << "S-(t) = " << Mk - Sk <<std::endl;
460  }
461  float limitDown = 0.f, limitUp = 0.f;
462  p_test->getLimits(limitDown, limitUp);
463  std::cout << "\tLimit down = " << limitDown << std::endl;
464  std::cout << "\tLimit up = " << limitUp << std::endl;
466  std::cout << "End of test on synthetic data. Press enter to leave." << std::endl;
467  std::cin.get();
468  delete p_test;
469  return EXIT_SUCCESS;
470 }
471 
472 int main(int argc, char *argv[])
473 {
476  float opt_mean = 6.f;
477  float opt_meandrift = 0.f;
478  float opt_stdev = 2.f;
479 
480  int i = 1;
481  while (i < argc) {
482  if ((std::string(argv[i]) == "--test") && ((i + 1) < argc)) {
483  opt_typeTest = TutorialMeanDrift::typeTestFromString(argv[i + 1]);
484  ++i;
485  }
486  else if ((std::string(argv[i]) == "--nb-samples") && ((i + 1) < argc)) {
487  parameters.m_test_nbsamples = std::atoi(argv[i + 1]);
488  ++i;
489  }
490  else if ((std::string(argv[i]) == "--mean") && ((i + 1) < argc)) {
491  opt_mean = static_cast<float>(std::atof(argv[i + 1]));
492  ++i;
493  }
494  else if ((std::string(argv[i]) == "--mean-drift") && ((i + 1) < argc)) {
495  opt_meandrift = static_cast<float>(std::atof(argv[i + 1]));
496  ++i;
497  }
498  else if ((std::string(argv[i]) == "--stdev") && ((i + 1) < argc)) {
499  opt_stdev = static_cast<float>(std::atof(argv[i + 1]));
500  ++i;
501  }
502  else if ((std::string(argv[i]) == "--alarms")) {
503  unsigned int nbArguments = 0;
504  std::vector<std::string> alarmNames;
505  bool hasNotFoundNextParams = true;
506  for (int j = 1; ((i + j) < argc) && hasNotFoundNextParams; ++j) {
507  std::string candidate(argv[i+j]);
508  if (candidate.find("--") != std::string::npos) {
509  // This is the next command line parameter
510  hasNotFoundNextParams = false;
511  }
512  else {
513  // This is a name
514  alarmNames.push_back(candidate);
515  ++nbArguments;
516  }
517  }
520  i += nbArguments;
521  }
522  else if ((std::string(argv[i]) == "--cusum-h") && ((i + 1) < argc)) {
523  parameters.m_cusum_h = static_cast<float>(std::atof(argv[i + 1]));
524  ++i;
525  }
526  else if ((std::string(argv[i]) == "--cusum-k") && ((i + 1) < argc)) {
527  parameters.m_cusum_k = static_cast<float>(std::atof(argv[i + 1]));
528  ++i;
529  }
530  else if ((std::string(argv[i]) == "--ewma-alpha") && ((i + 1) < argc)) {
531  parameters.m_ewma_alpha = static_cast<float>(std::atof(argv[i + 1]));
532  ++i;
533  }
534  else if ((std::string(argv[i]) == "--hinkley-alpha") && ((i + 1) < argc)) {
535  parameters.m_hinkley_alpha = static_cast<float>(std::atof(argv[i + 1]));
536  ++i;
537  }
538  else if ((std::string(argv[i]) == "--hinkley-delta") && ((i + 1) < argc)) {
539  parameters.m_hinkley_delta = static_cast<float>(std::atof(argv[i + 1]));
540  ++i;
541  }
542  else if (std::string(argv[i]) == "--hinkley-compute") {
543  parameters.m_hinkley_computealphadelta = true;
544  }
545  else if ((std::string(argv[i]) == "--hinkley-h") && ((i + 1) < argc)) {
546  parameters.m_hinkley_h = static_cast<float>(std::atof(argv[i + 1]));
547  ++i;
548  }
549  else if ((std::string(argv[i]) == "--hinkley-k") && ((i + 1) < argc)) {
550  parameters.m_hinkley_k = static_cast<float>(std::atof(argv[i + 1]));
551  ++i;
552  }
553  else if ((std::string(argv[i]) == "--shewhart-rules") && (i + vpStatisticalTestShewhart::COUNT_WECO - 1 < argc)) {
554  for (int j = 0; j < vpStatisticalTestShewhart::COUNT_WECO - 1; ++j) {
555  std::string argument = std::string(argv[i + 1 + j]);
556  if ((argument.find("on") != std::string::npos) || (argument.find("ON") != std::string::npos)) {
557  parameters.m_shewhart_rules[j] = true;
558  }
559  else {
560  parameters.m_shewhart_rules[j] = false;
561  }
562  }
564  }
565  else if (std::string(argv[i]) == "--shewhart-weco") {
566  parameters.m_shewhart_useWECO = true;
567  }
568  else if ((std::string(argv[i]) == "--sigma-h") && ((i + 1) < argc)) {
569  parameters.m_sigma_h = static_cast<float>(std::atof(argv[i + 1]));
570  ++i;
571  }
572  else if ((std::string(argv[i]) == "--help") || (std::string(argv[i]) == "-h")) {
573  std::cout << "\nSYNOPSIS " << std::endl
574  << argv[0]
575  << " [--test <type>]"
576  << " [--nb-samples <value>]"
577  << " [--alarms <name_1 ... name_n>]"
578  << " [--mean <value>]"
579  << " [--mean-drift <value>]"
580  << " [--stdev <value>]"
581  << " [--cusum-h <value>]"
582  << " [--cusum-k <value>]"
583  << " [--ewma-alpha <value ]0; 1[>]"
584  << " [--hinkley-alpha <]0; inf[>]"
585  << " [--hinkley-delta <]0; inf[>]"
586  << " [--hinkley-compute]"
587  << " [--hinkley-h <]0; inf[>]"
588  << " [--hinkley-k <]0; inf[>]"
589  << " [--shewhart-rules <3-sigma:{on|off} 2-sigma:{on|off} 1-sigma:{on|off} same-side:{on|off}>"
590  << " [--shewhart-weco]"
591  << " [--sigma-h <value>]"
592  << " [--help,-h]" << std::endl;
593  std::cout << "\nOPTIONS " << std::endl
594  << " --test <type-name>" << std::endl
595  << " Type of test to perform on the data." << std::endl
596  << " Available values: " << TutorialMeanDrift::getAvailableTypeTest() << std::endl
597  << std::endl
598  << " --nb-samples <value>" << std::endl
599  << " Number of samples to compute the mean and standard deviation of the monitored signal." << std::endl
600  << " Default: " << parameters.m_test_nbsamples << std::endl
601  << std::endl
602  << " --alarms <name_1 .. name_n>" << std::endl
603  << " Set the mean drift alarms to monitor." << std::endl
604  << " Default: " << TutorialMeanDrift::meanDriftArrayToString(parameters.m_test_activatedalarms) << std::endl
605  << " Available: " << vpStatisticalTestAbstract::getAvailableMeanDriftType() << std::endl
606  << std::endl
607  << " --mean <value>" << std::endl
608  << " Mean of the signal." << std::endl
609  << " Default: " << opt_mean<< std::endl
610  << std::endl
611  << " --mean-drift <value>" << std::endl
612  << " Mean drift for the synthetic data." << std::endl
613  << " Default: " << opt_meandrift << std::endl
614  << std::endl
615  << " --stdev <value>" << std::endl
616  << " Standard deviation of the signal." << std::endl
617  << " Default: " << opt_stdev << std::endl
618  << std::endl
619  << " --cusum-h <value>" << std::endl
620  << " The alarm factor that permits to the CUSUM test to determine when the process is out of control" << std::endl
621  << " from the standard deviation of the signal." << std::endl
622  << " Default: " << parameters.m_cusum_h << std::endl
623  << std::endl
624  << " --cusum-k <value>" << std::endl
625  << " The factor that permits to determine the slack of the CUSUM test, " << std::endl
626  << " i.e. the minimum value of the jumps we want to detect, from the standard deviation of the signal." << std::endl
627  << " Default: " << parameters.m_cusum_k << std::endl
628  << std::endl
629  << " --ewma-alpha <value ]0; 1[>" << std::endl
630  << " Forgetting factor for the Exponential Weighted Moving Average (EWMA)." << std::endl
631  << " Default: " << parameters.m_ewma_alpha << std::endl
632  << std::endl
633  << " --hinkley-alpha <value ]0; inf[>" << std::endl
634  << " The alarm threshold indicating that a mean drift occurs for the Hinkley's test." << std::endl
635  << " Default: " << parameters.m_hinkley_alpha << std::endl
636  << std::endl
637  << " --hinkley-delta <value>" << std::endl
638  << " Detection threshold indicating minimal magnitude we want to detect for the Hinkley's test." << std::endl
639  << " Default: " << parameters.m_hinkley_delta << std::endl
640  << std::endl
641  << " --hinkley-compute" << std::endl
642  << " If set, the Hinkley's test will compute the alarm and detection thresholds" << std::endl
643  << " from the standard deviation of the input signal." << std::endl
644  << " Default: disabled" << std::endl
645  << std::endl
646  << " --hinkley-h <value>" << std::endl
647  << " Alarm factor permitting to compute the alarm threshold for the Hinkley's test." << std::endl
648  << " Default: " << parameters.m_hinkley_h << std::endl
649  << std::endl
650  << " --hinkley-k <value>" << std::endl
651  << " Detection factor permitting to compute the Detection threshold for the Hinkley's test." << std::endl
652  << " Default: " << parameters.m_hinkley_k << std::endl
653  << std::endl
654  << " --shewhart-rules <3-sigma:{on|off} 2-sigma:{on|off} 1-sigma:{on|off} same-side:{on|off}>" << std::endl
655  << " Choose the WECO additionnal tests for the Shewhart's test to use. To activate them, --shewart-weco must be used." << std::endl
656  << " Default: ON ON ON ON" << std::endl
657  << std::endl
658  << " --shewhart-weco" << std::endl
659  << " Activate the WECO additionnal tests for the Shewhart's test." << std::endl
660  << " Default: deactivated" << std::endl
661  << std::endl
662  << " --sigma-h <value>" << std::endl
663  << " The alarm factor of the sigma test." << std::endl
664  << " Default: " << parameters.m_sigma_h << std::endl
665  << std::endl
666  << " --help, -h" << std::endl
667  << " Display this helper message." << std::endl
668  << std::endl;
669  return EXIT_SUCCESS;
670  }
671  else {
672  std::cout << "\nERROR " << std::endl << " Unknown option " << argv[i] << std::endl;
673  return EXIT_FAILURE;
674  }
675  ++i;
676  }
677 
678  if (parameters.m_test_nbactivatedalarms == 0) {
679  throw(vpException(vpException::badValue, "Error, at least one type of alarm must be monitored. See " + std::string(argv[0]) + " --help"));
680  return EXIT_FAILURE;
681  }
682 
683  std::cout << " Activated statistical test : " << TutorialMeanDrift::typeTestToString(opt_typeTest) << std::endl;
684  std::cout << " Activated alarms : " << TutorialMeanDrift::meanDriftArrayToString(parameters.m_test_activatedalarms) << std::endl;
685  std::cout << " Nb samples for statistics computation: " << parameters.m_test_nbsamples << std::endl;
686  std::cout << " Alarm factor CUSUM test : " << (opt_typeTest == TutorialMeanDrift::MEAN_ADJUSTED_CUSUM_TYPE_TEST ? TutorialMeanDrift::numberToString(parameters.m_cusum_h) : "N/A") << std::endl;
687  std::cout << " Detection factor CUSUM test : " << (opt_typeTest == TutorialMeanDrift::MEAN_ADJUSTED_CUSUM_TYPE_TEST ? TutorialMeanDrift::numberToString(parameters.m_cusum_k) : "N/A") << std::endl;
688  std::cout << " Forgetting factor EWMA test : " << (opt_typeTest == TutorialMeanDrift::EWMA_TYPE_TEST ? TutorialMeanDrift::numberToString(parameters.m_ewma_alpha) : "N/A") << std::endl;
689  std::cout << " Alarm threshold Hinkley's test : " << ((opt_typeTest == TutorialMeanDrift::HINLKEY_TYPE_TEST) && (!parameters.m_hinkley_computealphadelta) ? TutorialMeanDrift::numberToString(parameters.m_hinkley_alpha) : "N/A") << std::endl;
690  std::cout << " Detection threshold Hinkley's test : " << ((opt_typeTest == TutorialMeanDrift::HINLKEY_TYPE_TEST) && (!parameters.m_hinkley_computealphadelta) ? TutorialMeanDrift::numberToString(parameters.m_hinkley_delta) : "N/A") << std::endl;
691  std::cout << " Alarm factor Hinkley's test : " << ((opt_typeTest == TutorialMeanDrift::HINLKEY_TYPE_TEST) && parameters.m_hinkley_computealphadelta ? TutorialMeanDrift::numberToString(parameters.m_hinkley_h) : "N/A") << std::endl;
692  std::cout << " Detection factor Hinkley's test : " << ((opt_typeTest == TutorialMeanDrift::HINLKEY_TYPE_TEST) && parameters.m_hinkley_computealphadelta ? TutorialMeanDrift::numberToString(parameters.m_hinkley_k) : "N/A") << std::endl;
693  std::cout << " Shewhart's test set of WECO rules : " << (parameters.m_shewhart_useWECO && (opt_typeTest == TutorialMeanDrift::SHEWHART_TYPE_TEST) ? TutorialMeanDrift::wecoRulesToString(parameters.m_shewhart_rules) : "N/A") << std::endl;
694  std::cout << " Shewhart's test use WECO rules : " << (opt_typeTest == TutorialMeanDrift::SHEWHART_TYPE_TEST ? TutorialMeanDrift::boolToString(parameters.m_shewhart_useWECO && (opt_typeTest == TutorialMeanDrift::SHEWHART_TYPE_TEST)) : "N/A") << std::endl;
695  std::cout << " Alarm factor Sigma test : " << (opt_typeTest == TutorialMeanDrift::SIGMA_TYPE_TEST ? TutorialMeanDrift::numberToString(parameters.m_sigma_h) : "N/A") << std::endl;
696  std::cout << " Actual mean of the input signal: " << opt_mean << std::endl;
697  std::cout << " Actual stdev of the input signal: " << opt_stdev << std::endl;
698  std::cout << " Mean drift of the input signal: " << opt_meandrift << std::endl;
699 
700  return testOnSynthetic(opt_typeTest, parameters, opt_mean, opt_meandrift, opt_stdev);
701 }
702 #else
703 int main()
704 {
705  std::cerr << "Recompile ViSP with display capabilities in order to use this tutorial." << std::endl;
706  return EXIT_FAILURE;
707 }
708 #endif
error that can be emitted by ViSP classes.
Definition: vpException.h:59
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:85
Class for generating random number with normal probability density.
Definition: vpGaussRand.h:116
This class enables real time drawing of 2D or 3D graphics. An instance of the class open a window whi...
Definition: vpPlot.h:109
void initGraph(unsigned int graphNum, unsigned int curveNbr)
Definition: vpPlot.cpp:202
void setUnitY(unsigned int graphNum, const std::string &unity)
Definition: vpPlot.cpp:523
void plot(unsigned int graphNum, unsigned int curveNum, double x, double y)
Definition: vpPlot.cpp:269
void setUnitX(unsigned int graphNum, const std::string &unitx)
Definition: vpPlot.cpp:513
void setTitle(unsigned int graphNum, const std::string &title)
Definition: vpPlot.cpp:503
Base class for methods detecting the drift of the mean of a process.
vpMeanDriftType
Enum that indicates if a drift of the mean occurred.
static vpMeanDriftType vpMeanDriftTypeFromString(const std::string &name)
Cast a string into a vpMeanDriftType.
void getLimits(float &limitDown, float &limitUp) const
Get the upper and lower limits of the test signal.
static std::string vpMeanDriftTypeToString(const vpMeanDriftType &type)
Cast a vpMeanDriftType into a string.
vpMeanDriftType testDownUpwardMeanDrift(const float &signal)
Test if a downward or an upward mean drift occurred according to the new value of the signal.
float getMean() const
Get the mean used as reference.
float getStdev() const
Get the standard deviation used as reference.
static std::string getAvailableMeanDriftType(const std::string &prefix="<", const std::string &sep=" , ", const std::string &suffix=">")
Get the list of available vpMeanDriftType objects that are handled.
Class that permits to perform Exponentially Weighted Moving Average mean drft tests.
float getWt() const
Get the current value of the test signal.
This class implements the Hinkley's cumulative sum test.
float getNk() const
Get the minimum of the test signal for upward mean drift .
float getTk() const
Get the test signal for upward mean drift..
float getSk() const
Get the test signal for downward mean drift.
float getMk() const
Get the maximum of the test signal for downward mean drift .
Class that permits to perform a mean adjusted Cumulative Sum test.
float getTestSignalMinus() const
Get the latest value of the test signal for downward jumps of the mean.
float getTestSignalPlus() const
Get the latest value of the test signal for upward jumps of the mean.
Class that permits a Shewhart's test.
vpWecoRulesAlarm getAlarm() const
Get the alarm raised by the last test due to the WECO's rules.
std::vector< float > getSignals() const
Get the NB_DATA_SIGNAL last signal values, sorted from the latest [0] to the newest [NB_DATA_SIGNAL -...
static const bool CONST_ALL_WECO_ACTIVATED[COUNT_WECO - 1]
static std::string vpWecoRulesAlarmToString(const vpWecoRulesAlarm &alarm)
Class that permits a simple test comparing the current value to the standard deviation of the signal.
TypeTest typeTestFromString(const std::string &name)
Permit to cast a string into a TypeTest, to cast a command line argument.
void vectorOfStringToMeanDriftTypeArray(const std::vector< std::string > &names, bool array[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT])
Cast a vector of string into an array of boolean activating / deactivating the mean drift alarms.
std::string meanDriftArrayToString(const bool array[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT], const std::string &prefix="[", const std::string &sep=" , ", const std::string &suffix="]")
Cast an array of boolean (de)activating the mean drift alarms into a single string listing all the al...
std::vector< std::string > meanDriftArrayToVectorOfString(const bool array[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT])
Cast an array of boolean (de)activating the mean drift alarms into the corresponding vector of string...
std::string getAvailableTypeTest(const std::string &prefix="<", const std::string &sep=" , ", const std::string &suffix=">")
Get the list of available TypeTest objects that are handled.
std::string typeTestToString(const TypeTest &type)
[Enum_For_Test_Choice]
std::string numberToString(const T &number)
Cast a number type into a string.
const bool CONST_ALL_ALARM_OFF[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT]
Array that sets all the types of mean drift to deactivated.
struct TutorialMeanDrift::ParametersForAlgo ParametersForAlgo
[Structure_Parameters]
std::string boolToString(const bool &boolean)
Cast a boolean into a string.
const bool CONST_ALL_ALARM_ON[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT]
Array that sets all the types of mean drift to activated.
std::string wecoRulesToString(const bool rules[vpStatisticalTestShewhart::COUNT_WECO - 1], const std::string &prefix="[", const std::string &suffix="]", const std::string &sep=" , ")
Write the WECO's rules used in the Shewhart's test in human readable format.
TypeTest
[Enum_For_Test_Choice]
unsigned int meanDriftArrayToNbActivated(const bool array[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT])
Indicate how many alarms are set.
bool m_shewhart_rules[vpStatisticalTestShewhart::COUNT_WECO - 1]
bool m_test_activatedalarms[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT]