Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpStatisticalTestHinkley.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 */
30
38
39#include <visp3/core/vpStatisticalTestHinkley.h>
40#include <visp3/core/vpMath.h>
41
42#include <cmath> // std::fabs
43#include <iostream>
44#include <limits> // numeric_limits
45#include <stdio.h>
46#include <stdlib.h>
47
51 , m_dmin2(0.1f)
52 , m_alpha(0.2f)
53 , m_Sk(0.f)
54 , m_Mk(0.f)
55 , m_Tk(0.f)
56 , m_Nk(0.f)
58 , m_h(4.76f)
59 , m_k(1.f)
60{
61 init();
62}
63
64vpStatisticalTestHinkley::vpStatisticalTestHinkley(const float &alpha, const float &delta_val, const unsigned int &nbSamplesForInit)
66 , m_dmin2(delta_val / 2.f)
67 , m_alpha(alpha)
68 , m_Sk(0.f)
69 , m_Mk(0.f)
70 , m_Tk(0.f)
71 , m_Nk(0.f)
73 , m_h(4.76f)
74 , m_k(1.f)
75{
76 init(alpha, delta_val, nbSamplesForInit);
77}
78
79vpStatisticalTestHinkley::vpStatisticalTestHinkley(const float &h, const float &k, const bool &computeAlphaDeltaFromStdev, const unsigned int &nbSamplesForInit)
81{
82 init(h, k, computeAlphaDeltaFromStdev, nbSamplesForInit);
83}
84
85vpStatisticalTestHinkley::vpStatisticalTestHinkley(const float &h, const float &k, const float &mean, const float &stdev)
87{
88 init(h, k, mean, stdev);
89}
90
92{
96
97 m_Sk = 0.f;
98 m_Mk = 0.f;
99
100 m_Tk = 0.f;
101 m_Nk = 0.f;
102
104}
105
106void vpStatisticalTestHinkley::init(const float &alpha, const float &delta_val, const unsigned int &nbSamplesForInit)
107{
108 init();
109 setNbSamplesForStat(nbSamplesForInit);
110 setAlpha(alpha);
111 setDelta(delta_val);
113}
114
115void vpStatisticalTestHinkley::init(const float &alpha, const float &delta_val, const float &mean)
116{
117 init();
118 setAlpha(alpha);
119 setDelta(delta_val);
120 m_mean = mean;
123}
124
125void vpStatisticalTestHinkley::init(const float &h, const float &k, const bool &computeAlphaDeltaFromStdev, const unsigned int &nbSamples)
126{
127 if (!computeAlphaDeltaFromStdev) {
128 throw(vpException(vpException::badValue, "computeAlphaDeltaFromStdev must be true, or use another init function"));
129 }
130 init();
131 setNbSamplesForStat(nbSamples);
132 m_h = h;
133 m_k = k;
135}
136
137void vpStatisticalTestHinkley::init(const float &h, const float &k, const float &mean, const float &stdev)
138{
139 init();
140 m_mean = mean;
141 m_stdev = stdev;
142 m_h = h;
143 m_k = k;
147}
148
149void vpStatisticalTestHinkley::setDelta(const float &delta) { m_dmin2 = delta / 2.f; }
150
152{
153 this->m_alpha = alpha;
156}
157
159{
160 float delta = m_k * m_stdev;
161 setDelta(delta);
162 float alpha = m_h * m_stdev;
163 setAlpha(alpha);
164}
165
167{
168 // When the mean slowly increases or decreases, especially after an abrupt change of the mean,
169 // the means tends to drift. To reduce the drift of the mean
170 // it is updated with the current value of the signal only if
171 // a beginning of a mean drift is not detected,
172 // i.e. if ( ((m_Mk-m_Sk) == 0) && ((m_Tk-m_Nk) == 0) )
173 if ((std::fabs(m_Mk - m_Sk) <= std::fabs(vpMath::maximum(m_Mk, m_Sk)) * std::numeric_limits<float>::epsilon()) &&
174 (std::fabs(m_Tk - m_Nk) <= std::fabs(vpMath::maximum(m_Tk, m_Nk)) * std::numeric_limits<float>::epsilon())) {
175 m_mean = (m_mean * (m_count - 1) + static_cast<float>(signal)) / (m_count);
176 }
177}
178
180{
181 m_Sk += static_cast<float>(signal) - m_mean + m_dmin2;
182}
183
185{
186 if (m_Sk > m_Mk) {
187 m_Mk = m_Sk;
188 }
189}
190
192{
193 m_Tk += static_cast<float>(signal) - m_mean - m_dmin2;
194}
195
197{
198 if (m_Tk < m_Nk) {
199 m_Nk = m_Tk;
200 }
201}
202
211
220
222{
223 bool updateStats = vpStatisticalTestAbstract::updateStatistics(signal);
225 // If needed, compute alpha and delta
228 }
229 // Initialize the test signals
230 m_Mk = 0.f;
231 m_Nk = 0.f;
232 m_Sk = 0.f;
233 m_Tk = 0.f;
234 }
235 return updateStats;
236}
237
239{
240 double signal_ = static_cast<float>(signal);
241 computeSk(signal_);
242 computeTk(signal_);
243
244 computeMk();
245 computeNk();
246
247 ++m_count;
248 computeMean(signal_);
249}
250END_VISP_NAMESPACE
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition vpException.h:73
static Type maximum(const Type &a, const Type &b)
Definition vpMath.h:257
vpMeanDriftType
Enum that indicates if a drift of the mean occurred.
void init()
(Re)Initialize the algorithm.
vpStatisticalTestAbstract()
Construct a new vpStatisticalTestAbstract object.
virtual bool updateStatistics(const float &signal)
Update m_s and if enough values are available, compute the mean, the standard deviation and the limit...
void setNbSamplesForStat(const unsigned int &nbSamples)
Set the number of samples required to compute the mean and standard deviation of the signal and alloc...
vpStatisticalTestHinkley()
Construct a new vpStatisticalTestHinkley object. Call init() to initialise the Hinkley's test and set...
void setAlpha(const float &alpha)
The threshold indicating that a mean drift occurs.
virtual vpMeanDriftType detectDownwardMeanDrift() VP_OVERRIDE
Detects if a downward mean drift occurred.
virtual void computeAlphaDelta()
Compute and from the standard deviation of the signal.
void setDelta(const float &delta)
Set the drift minimal magnitude that we want to detect.
void computeTk(double signal)
Compute .
void computeMk()
Compute , the maximum value of .
virtual vpMeanDriftType detectUpwardMeanDrift() VP_OVERRIDE
Detects if an upward mean drift occurred on the mean.
void computeNk()
Compute , the minimum value of .
virtual bool updateStatistics(const float &signal) VP_OVERRIDE
Update m_s and if enough values are available, compute the mean, the standard deviation and the limit...
void computeSk(double signal)
Compute .
void init()
Initialise the Hinkley's test by setting the mean signal value to zero as well as .
void computeMean(double signal)
Compute the mean value of the signal. The mean value must be computed before the mean drift is estim...
virtual void updateTestSignals(const float &signal) VP_OVERRIDE
Update the test signals.