Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpHinkley.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
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 http://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  * Description:
31  * Hinkley's cumulative sum test implementation.
32  *
33  * Authors:
34  * Fabien Spindler
35  *
36  *****************************************************************************/
37 
47 #include <visp3/core/vpHinkley.h>
48 #include <visp3/core/vpDebug.h>
49 //#include <visp3/core/vpIoTools.h>
50 #include <visp3/core/vpMath.h>
51 
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <iostream>
55 #include <cmath> // std::fabs
56 #include <limits> // numeric_limits
57 
58 /* VP_DEBUG_MODE fixed by configure:
59  1:
60  2:
61  3: Print data
62 */
63 
64 
77  : dmin2(0.1), alpha(0.2), nsignal(0), mean(0), Sk(0), Mk(0), Tk(0), Nk(0)
78 {
79 }
80 
97 vpHinkley::vpHinkley(double alpha_val, double delta_val)
98  : dmin2(delta_val/2.), alpha(alpha_val), nsignal(0), mean(0), Sk(0), Mk(0), Tk(0), Nk(0)
99 {
100 }
101 
115 void
116 vpHinkley::init(double alpha_val, double delta_val)
117 {
118  init();
119 
120  setAlpha(alpha_val);
121  setDelta(delta_val);
122 }
123 
130 {
131 }
132 
140 {
141  nsignal = 0;
142  mean = 0.0;
143 
144  Sk = 0;
145  Mk = 0;
146 
147  Tk = 0;
148  Nk = 0;
149 }
150 
159 void vpHinkley::setDelta(double delta)
160 {
161  dmin2 = delta / 2;
162 }
163 
171 void vpHinkley::setAlpha(double alpha_val)
172 {
173  this->alpha = alpha_val;
174 }
175 
187 {
188 
189  vpHinkleyJumpType jump = noJump;
190 
191  nsignal ++; // Signal length
192 
193  if (nsignal == 1) mean = signal;
194 
195  // Calcul des variables cumulees
196  computeSk(signal);
197 
198  computeMk();
199 
200  vpCDEBUG(2) << "alpha: " << alpha << " dmin2: " << dmin2
201  << " signal: " << signal << " Sk: " << Sk << " Mk: " << Mk;
202 
203  // teste si les variables cumulees excedent le seuil
204  if ((Mk - Sk) > alpha)
205  jump = downwardJump;
206 
207 #ifdef VP_DEBUG
208  if (VP_DEBUG_MODE >=2) {
209  switch(jump) {
210  case noJump:
211  std::cout << "noJump " << std::endl;
212  break;
213  case downwardJump:
214  std::cout << "downWardJump " << std::endl;
215  break;
216  case upwardJump:
217  std::cout << "upwardJump " << std::endl;
218  break;
219  }
220  }
221 #endif
222 
223  computeMean(signal);
224 
225  if (jump == downwardJump) {
226  vpCDEBUG(2) << "\n*** Reset the Hinkley test ***\n";
227 
228  Sk = 0; Mk = 0; nsignal = 0;
229  }
230 
231  return (jump);
232 }
233 
245 {
246 
247  vpHinkleyJumpType jump = noJump;
248 
249  nsignal ++; // Signal length
250 
251  if (nsignal == 1) mean = signal;
252 
253  // Calcul des variables cumulees
254  computeTk(signal);
255 
256  computeNk();
257 
258  vpCDEBUG(2) << "alpha: " << alpha << " dmin2: " << dmin2
259  << " signal: " << signal << " Tk: " << Tk << " Nk: " << Nk;
260 
261  // teste si les variables cumulees excedent le seuil
262  if ((Tk - Nk) > alpha)
263  jump = upwardJump;
264 
265 #ifdef VP_DEBUG
266  if (VP_DEBUG_MODE >= 2) {
267  switch(jump) {
268  case noJump:
269  std::cout << "noJump " << std::endl;
270  break;
271  case downwardJump:
272  std::cout << "downWardJump " << std::endl;
273  break;
274  case upwardJump:
275  std::cout << "upWardJump " << std::endl;
276  break;
277  }
278  }
279 #endif
280  computeMean(signal);
281 
282  if (jump == upwardJump) {
283  vpCDEBUG(2) << "\n*** Reset the Hinkley test ***\n";
284 
285  Tk = 0; Nk = 0; nsignal = 0;
286  }
287 
288  return (jump);
289 }
290 
302 {
303 
304  vpHinkleyJumpType jump = noJump;
305 
306  nsignal ++; // Signal length
307 
308  if (nsignal == 1) mean = signal;
309 
310  // Calcul des variables cumulees
311  computeSk(signal);
312  computeTk(signal);
313 
314  computeMk();
315  computeNk();
316 
317  vpCDEBUG(2) << "alpha: " << alpha << " dmin2: " << dmin2
318  << " signal: " << signal
319  << " Sk: " << Sk << " Mk: " << Mk
320  << " Tk: " << Tk << " Nk: " << Nk << std::endl;
321 
322  // teste si les variables cumulees excedent le seuil
323  if ((Mk - Sk) > alpha)
324  jump = downwardJump;
325  else if ((Tk - Nk) > alpha)
326  jump = upwardJump;
327 
328 #ifdef VP_DEBUG
329  if (VP_DEBUG_MODE >= 2) {
330  switch(jump) {
331  case noJump:
332  std::cout << "noJump " << std::endl;
333  break;
334  case downwardJump:
335  std::cout << "downWardJump " << std::endl;
336  break;
337  case upwardJump:
338  std::cout << "upwardJump " << std::endl;
339  break;
340  }
341  }
342 #endif
343 
344  computeMean(signal);
345 
346  if ((jump == upwardJump) || (jump == downwardJump)) {
347  vpCDEBUG(2) << "\n*** Reset the Hinkley test ***\n";
348 
349  Sk = 0; Mk = 0; Tk = 0; Nk = 0; nsignal = 0;
350  // Debut modif FS le 03/09/2003
351  mean = signal;
352  // Fin modif FS le 03/09/2003
353  }
354 
355  return (jump);
356 }
357 
366 void vpHinkley::computeMean(double signal)
367 {
368  // Debut modif FS le 03/09/2003
369  // Lors d'une chute ou d'une remontee lente du signal, pariculierement
370  // apres un saut, la moyenne a tendance a "deriver". Pour reduire ces
371  // derives de la moyenne, elle n'est remise a jour avec la valeur
372  // courante du signal que si un debut de saut potentiel n'est pas detecte.
373  //if ( ((Mk-Sk) == 0) && ((Tk-Nk) == 0) )
374  if ( ( std::fabs(Mk-Sk) <= std::fabs(vpMath::maximum(Mk,Sk))*std::numeric_limits<double>::epsilon() )
375  &&
376  ( std::fabs(Tk-Nk) <= std::fabs(vpMath::maximum(Tk,Nk))*std::numeric_limits<double>::epsilon() ) )
377  // Fin modif FS le 03/09/2003
378 
379  // Mise a jour de la moyenne.
380  mean = (mean * (nsignal - 1) + signal) / (nsignal);
381 
382 }
390 void vpHinkley::computeSk(double signal)
391 {
392 
393  // Calcul des variables cumulees
394  Sk += signal - mean + dmin2;
395 }
401 void vpHinkley::computeMk()
402 {
403  if (Sk > Mk) Mk = Sk;
404 }
411 void vpHinkley::computeTk(double signal)
412 {
413 
414  // Calcul des variables cumulees
415  Tk += signal - mean - dmin2;
416 }
422 void vpHinkley::computeNk()
423 {
424  if (Tk < Nk) Nk = Tk;
425 }
426 
428 {
429  switch(jump)
430  {
431  case noJump :
432  std::cout << " No jump detected " << std::endl ;
433  break ;
434  case downwardJump :
435  std::cout << " Jump downward detected " << std::endl ;
436  break ;
437  case upwardJump :
438  std::cout << " Jump upward detected " << std::endl ;
439  break ;
440  default:
441  std::cout << " Jump detected " << std::endl ;
442  break ;
443 
444  }
445 }
446 
vpHinkleyJumpType testDownUpwardJump(double signal)
Definition: vpHinkley.cpp:301
vpHinkleyJumpType
Definition: vpHinkley.h:101
vpHinkleyJumpType testUpwardJump(double signal)
Definition: vpHinkley.cpp:244
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:140
#define vpCDEBUG(level)
Definition: vpDebug.h:502
static void print(vpHinkleyJumpType jump)
Definition: vpHinkley.cpp:427
void init()
Definition: vpHinkley.cpp:139
vpHinkleyJumpType testDownwardJump(double signal)
Definition: vpHinkley.cpp:186
void setAlpha(double alpha)
Definition: vpHinkley.cpp:171
void setDelta(double delta)
Definition: vpHinkley.cpp:159