#include <cstring>
#include <visp3/core/vpConfig.h>
#include <visp3/core/vpGaussRand.h>
#include <visp3/core/vpStatisticalTestEWMA.h>
#include <visp3/core/vpStatisticalTestHinkley.h>
#include <visp3/core/vpStatisticalTestMeanAdjustedCUSUM.h>
#include <visp3/core/vpStatisticalTestShewhart.h>
#include <visp3/core/vpStatisticalTestSigma.h>
#include <visp3/gui/vpPlot.h>
#if defined(VISP_HAVE_DISPLAY)
{
{
{
std::string result;
switch (type) {
result = "hinkley";
break;
result = "ewma";
break;
result = "cusum";
break;
result = "shewhart";
break;
result = "sigma";
break;
default:
result = "unknown-type-test";
break;
}
return result;
}
{
unsigned int id = 0;
bool hasNotFound = true;
while ((id < count) && hasNotFound) {
result = temp;
hasNotFound = false;
}
++id;
}
return result;
}
const std::string &suffix = ">")
{
std::string msg(prefix);
unsigned int lastId = count - 1;
for (unsigned int i = 0; i < lastId; i++) {
}
return msg;
}
template <typename T>
{
std::stringstream ss;
ss << number;
return ss.str();
}
{
if (boolean) {
return "true";
}
else {
return "false";
}
}
{
std::string rulesAsString = prefix;
if (rules[i]) {
rulesAsString += "ON";
}
else {
rulesAsString += "OFF";
}
rulesAsString += sep;
}
rulesAsString += "ON";
}
else {
rulesAsString += "OFF";
}
rulesAsString += suffix;
return rulesAsString;
}
{
size_t nbNames = names.size();
for (size_t i = 0; i < nbNames; ++i) {
std::cout << "alarm[" << names[i] << "] (i.e. " << static_cast<unsigned int>(alarmToActivate) << ") set to true" << std::endl;
array[static_cast<unsigned int>(alarmToActivate)] = true;
}
}
}
}
{
std::vector<std::string> listActivatedAlarms;
for (unsigned int id = 0; id < nbTypeTests; ++id) {
if (array[id]) {
listActivatedAlarms.push_back(testName);
}
}
return listActivatedAlarms;
}
const std::string &prefix = "[", const std::string &sep = " , ",
const std::string &suffix = "]")
{
std::string result = prefix;
size_t nbTestActivated = listActivatedAlarms.size();
if (nbTestActivated == 0) {
return prefix + " " + suffix;
}
for (size_t i = 0; i < nbTestActivated - 1; ++i) {
result += listActivatedAlarms[i] + sep;
}
result += listActivatedAlarms[nbTestActivated - 1] + suffix;
return result;
}
{
unsigned int nbActivated = 0;
for (unsigned int id = 0; id < nbTypeAlarms; ++id) {
if (array[id]) {
++nbActivated;
}
}
return nbActivated;
}
{
{
}
}
const float &mean, const float &mean_drift, const float &stdev)
{
const float dt = 10.f;
plotter.initGraph(0, 1);
plotter.setTitle(0, "Evolution of the signal");
plotter.setUnitX(0, "Frame ID");
plotter.setUnitY(0, "No units");
unsigned int idFrame = 0;
switch (type) {
break;
break;
break;
break;
break;
default:
break;
}
delete p_test;
}
float signal;
vpGaussRand rndGen(stdev, mean,
static_cast<long>(idFrame * dt));
signal = static_cast<float>(rndGen());
++idFrame;
}
std::cout <<
"Estimated mean of the input signal: " << p_test->
getMean() << std::endl;
std::cout <<
"Estimated stdev of the input signal: " << p_test->
getStdev() << std::endl;
float mean_eff = mean;
bool hasToRun = true;
while (hasToRun) {
vpGaussRand rndGen(stdev, mean_eff,
static_cast<long>(idFrame * dt));
signal = static_cast<float>(rndGen());
hasToRun = false;
}
else {
mean_eff += mean_drift;
++idFrame;
}
}
std::cout <<
"Test failed at frame: " << idFrame - parameters.
m_test_nbsamples << std::endl;
std::cout << "Last signal value: " << signal << std::endl;
std::cout <<
"\tw(t) = " << p_testEwma->
getWt() << std::endl;
}
}
std::vector<float> signal = p_testShewhart->
getSignals();
size_t nbSignal = signal.size();
std::cout << "Signal history = [ ";
for (size_t i = 0; i < nbSignal; ++i) {
std::cout << signal[i] << " ";
}
std::cout << "]" << std::endl;
}
float Mk = p_hinkley->
getMk();
float Nk = p_hinkley->
getNk();
float Sk = p_hinkley->
getSk();
float Tk = p_hinkley->
getTk();
std::cout << "S+(t) = " << Tk - Nk <<std::endl;
std::cout << "S-(t) = " << Mk - Sk <<std::endl;
}
float limitDown = 0.f, limitUp = 0.f;
std::cout << "\tLimit down = " << limitDown << std::endl;
std::cout << "\tLimit up = " << limitUp << std::endl;
std::cout << "End of test on synthetic data. Press enter to leave." << std::endl;
std::cin.get();
delete p_test;
return EXIT_SUCCESS;
}
int main(int argc, char *argv[])
{
float opt_mean = 6.f;
float opt_meandrift = 0.f;
float opt_stdev = 2.f;
int i = 1;
while (i < argc) {
if ((std::string(argv[i]) == "--test") && ((i + 1) < argc)) {
++i;
}
else if ((std::string(argv[i]) == "--nb-samples") && ((i + 1) < argc)) {
++i;
}
else if ((std::string(argv[i]) == "--mean") && ((i + 1) < argc)) {
opt_mean = static_cast<float>(std::atof(argv[i + 1]));
++i;
}
else if ((std::string(argv[i]) == "--mean-drift") && ((i + 1) < argc)) {
opt_meandrift = static_cast<float>(std::atof(argv[i + 1]));
++i;
}
else if ((std::string(argv[i]) == "--stdev") && ((i + 1) < argc)) {
opt_stdev = static_cast<float>(std::atof(argv[i + 1]));
++i;
}
else if ((std::string(argv[i]) == "--alarms")) {
unsigned int nbArguments = 0;
std::vector<std::string> alarmNames;
bool hasNotFoundNextParams = true;
for (int j = 1; ((i + j) < argc) && hasNotFoundNextParams; ++j) {
std::string candidate(argv[i+j]);
if (candidate.find("--") != std::string::npos) {
hasNotFoundNextParams = false;
}
else {
alarmNames.push_back(candidate);
++nbArguments;
}
}
i += nbArguments;
}
else if ((std::string(argv[i]) == "--cusum-h") && ((i + 1) < argc)) {
parameters.
m_cusum_h =
static_cast<float>(std::atof(argv[i + 1]));
++i;
}
else if ((std::string(argv[i]) == "--cusum-k") && ((i + 1) < argc)) {
parameters.
m_cusum_k =
static_cast<float>(std::atof(argv[i + 1]));
++i;
}
else if ((std::string(argv[i]) == "--ewma-alpha") && ((i + 1) < argc)) {
parameters.
m_ewma_alpha =
static_cast<float>(std::atof(argv[i + 1]));
++i;
}
else if ((std::string(argv[i]) == "--hinkley-alpha") && ((i + 1) < argc)) {
++i;
}
else if ((std::string(argv[i]) == "--hinkley-delta") && ((i + 1) < argc)) {
++i;
}
else if (std::string(argv[i]) == "--hinkley-compute") {
}
else if ((std::string(argv[i]) == "--hinkley-h") && ((i + 1) < argc)) {
parameters.
m_hinkley_h =
static_cast<float>(std::atof(argv[i + 1]));
++i;
}
else if ((std::string(argv[i]) == "--hinkley-k") && ((i + 1) < argc)) {
parameters.
m_hinkley_k =
static_cast<float>(std::atof(argv[i + 1]));
++i;
}
std::string argument = std::string(argv[i + 1 + j]);
if ((argument.find("on") != std::string::npos) || (argument.find("ON") != std::string::npos)) {
}
else {
}
}
}
else if (std::string(argv[i]) == "--shewhart-weco") {
}
else if ((std::string(argv[i]) == "--sigma-h") && ((i + 1) < argc)) {
parameters.
m_sigma_h =
static_cast<float>(std::atof(argv[i + 1]));
++i;
}
else if ((std::string(argv[i]) == "--help") || (std::string(argv[i]) == "-h")) {
std::cout << "\nSYNOPSIS " << std::endl
<< argv[0]
<< " [--test <type>]"
<< " [--nb-samples <value>]"
<< " [--alarms <name_1 ... name_n>]"
<< " [--mean <value>]"
<< " [--mean-drift <value>]"
<< " [--stdev <value>]"
<< " [--cusum-h <value>]"
<< " [--cusum-k <value>]"
<< " [--ewma-alpha <value ]0; 1[>]"
<< " [--hinkley-alpha <]0; inf[>]"
<< " [--hinkley-delta <]0; inf[>]"
<< " [--hinkley-compute]"
<< " [--hinkley-h <]0; inf[>]"
<< " [--hinkley-k <]0; inf[>]"
<< " [--shewhart-rules <3-sigma:{on|off} 2-sigma:{on|off} 1-sigma:{on|off} same-side:{on|off}>"
<< " [--shewhart-weco]"
<< " [--sigma-h <value>]"
<< " [--help,-h]" << std::endl;
std::cout << "\nOPTIONS " << std::endl
<< " --test <type-name>" << std::endl
<< " Type of test to perform on the data." << std::endl
<< std::endl
<< " --nb-samples <value>" << std::endl
<< " Number of samples to compute the mean and standard deviation of the monitored signal." << std::endl
<< std::endl
<< " --alarms <name_1 .. name_n>" << std::endl
<< " Set the mean drift alarms to monitor." << std::endl
<< std::endl
<< " --mean <value>" << std::endl
<< " Mean of the signal." << std::endl
<< " Default: " << opt_mean<< std::endl
<< std::endl
<< " --mean-drift <value>" << std::endl
<< " Mean drift for the synthetic data." << std::endl
<< " Default: " << opt_meandrift << std::endl
<< std::endl
<< " --stdev <value>" << std::endl
<< " Standard deviation of the signal." << std::endl
<< " Default: " << opt_stdev << std::endl
<< std::endl
<< " --cusum-h <value>" << std::endl
<< " The alarm factor that permits to the CUSUM test to determine when the process is out of control" << std::endl
<< " from the standard deviation of the signal." << std::endl
<<
" Default: " << parameters.
m_cusum_h << std::endl
<< std::endl
<< " --cusum-k <value>" << std::endl
<< " The factor that permits to determine the slack of the CUSUM test, " << std::endl
<< " i.e. the minimum value of the jumps we want to detect, from the standard deviation of the signal." << std::endl
<<
" Default: " << parameters.
m_cusum_k << std::endl
<< std::endl
<< " --ewma-alpha <value ]0; 1[>" << std::endl
<< " Forgetting factor for the Exponential Weighted Moving Average (EWMA)." << std::endl
<< std::endl
<< " --hinkley-alpha <value ]0; inf[>" << std::endl
<< " The alarm threshold indicating that a mean drift occurs for the Hinkley's test." << std::endl
<< std::endl
<< " --hinkley-delta <value>" << std::endl
<< " Detection threshold indicating minimal magnitude we want to detect for the Hinkley's test." << std::endl
<< std::endl
<< " --hinkley-compute" << std::endl
<< " If set, the Hinkley's test will compute the alarm and detection thresholds" << std::endl
<< " from the standard deviation of the input signal." << std::endl
<< " Default: disabled" << std::endl
<< std::endl
<< " --hinkley-h <value>" << std::endl
<< " Alarm factor permitting to compute the alarm threshold for the Hinkley's test." << std::endl
<< std::endl
<< " --hinkley-k <value>" << std::endl
<< " Detection factor permitting to compute the Detection threshold for the Hinkley's test." << std::endl
<< std::endl
<< " --shewhart-rules <3-sigma:{on|off} 2-sigma:{on|off} 1-sigma:{on|off} same-side:{on|off}>" << std::endl
<< " Choose the WECO additionnal tests for the Shewhart's test to use. To activate them, --shewart-weco must be used." << std::endl
<< " Default: ON ON ON ON" << std::endl
<< std::endl
<< " --shewhart-weco" << std::endl
<< " Activate the WECO additionnal tests for the Shewhart's test." << std::endl
<< " Default: deactivated" << std::endl
<< std::endl
<< " --sigma-h <value>" << std::endl
<< " The alarm factor of the sigma test." << std::endl
<<
" Default: " << parameters.
m_sigma_h << std::endl
<< std::endl
<< " --help, -h" << std::endl
<< " Display this helper message." << std::endl
<< std::endl;
return EXIT_SUCCESS;
}
else {
std::cout << "\nERROR " << std::endl << " Unknown option " << argv[i] << std::endl;
return EXIT_FAILURE;
}
++i;
}
return EXIT_FAILURE;
}
std::cout <<
" Nb samples for statistics computation: " << parameters.
m_test_nbsamples << std::endl;
std::cout << " Actual mean of the input signal: " << opt_mean << std::endl;
std::cout << " Actual stdev of the input signal: " << opt_stdev << std::endl;
std::cout << " Mean drift of the input signal: " << opt_meandrift << std::endl;
return testOnSynthetic(opt_typeTest, parameters, opt_mean, opt_meandrift, opt_stdev);
}
#else
int main()
{
std::cerr << "Recompile ViSP with display capabilities in order to use this tutorial." << std::endl;
return EXIT_FAILURE;
}
#endif
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
Class for generating random number with normal probability density.
This class enables real time drawing of 2D or 3D graphics. An instance of the class open a window whi...
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]
@ MEAN_ADJUSTED_CUSUM_TYPE_TEST
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_hinkley_computealphadelta
unsigned int m_test_nbactivatedalarms
unsigned int m_test_nbsamples
bool m_test_activatedalarms[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT]