Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpMath.h
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  * Simple mathematical function not available in the C math library (math.h).
32  *
33  * Authors:
34  * Eric Marchand
35  *
36  *****************************************************************************/
37 
46 #ifndef vpMATH_HH
47 #define vpMATH_HH
48 
49 #include <visp3/core/vpConfig.h>
50 
51 #include <math.h>
52 #include <limits>
53 #include <climits>
54 #include <algorithm>
55 #include <vector>
56 
57 #if defined(VISP_HAVE_FUNC_ISNAN) || defined(VISP_HAVE_FUNC_STD_ISNAN) || defined(VISP_HAVE_FUNC_ISINF) || defined(VISP_HAVE_FUNC_STD_ISINF) || defined(VISP_HAVE_FUNC_STD_ROUND)
58 # include <cmath>
59 #endif
60 
61 #if defined(_WIN32) // Not defined in Microsoft math.h
62 
63 # ifndef M_PI
64 # define M_PI 3.14159265358979323846
65 # endif
66 
67 # ifndef M_PI_2
68 # define M_PI_2 (M_PI/2.0)
69 # endif
70 
71 # ifndef M_PI_4
72 # define M_PI_4 (M_PI/4.0)
73 # endif
74 
75 #endif
76 
77 
87 class VISP_EXPORT vpMath
88 {
89  public:
90 
97  static inline double deg(double rad) { return (rad*180.0)/M_PI ; }
98 
104  static inline double rad(double deg) { return (deg*M_PI)/180.0 ; }
105 
110  static inline double sqr(double x) { return x*x ; }
111 
112  // factorial of x
113  static inline double fact(unsigned int x) ;
114 
115  // combinaison
116  static inline long double comb(unsigned int n, unsigned int p) ;
117 
118  // round x to the nearest integer
119  static inline int round(const double x) ;
120 
121  // return the sign of x (+-1)
122  static inline int (sign)(double x) ;
123 
124  // test if a number equals 0 (with threshold value)
125  static inline bool nul(double x, double s=0.001);
126 
127  // test if two numbers are equals (with a user defined threshold)
128  static inline bool equal(double x, double y, double s=0.001);
129 
130  // test if a number is greater than another (with a user defined threshold)
131  static inline bool greater(double x, double y, double s=0.001);
132 
133 
140  template <class Type> static Type maximum(const Type& a, const Type& b)
141  {
142  return (a > b) ? a : b;
143  }
144 
151  template <class Type> static Type minimum(const Type& a, const Type& b)
152  {
153  return (a < b) ? a : b;
154  }
155 
161  template <class Type> static Type abs(const Type& x)
162  {
163  return (x < 0) ? -x : x;
164  }
165 
166 
167  // sinus cardinal
168  static double sinc(double x) ;
169  static double sinc(double sinx, double x) ;
170  static double mcosc(double cosx, double x) ;
171  static double msinc(double sinx, double x) ;
172 
173  // sigmoid
174  static inline double sigmoid(double x, double x0=0.,double x1=1., double n=12.);
175 
182  template <class Type> static void swap(Type& a, Type& b)
183  {
184  Type tmp = b;
185  b = a;
186  a = tmp;
187  }
188 
189  static bool isNaN(const double value);
190  static bool isInf(const double value);
191 
192  template<typename _Tp> static inline _Tp saturate(unsigned char v) { return _Tp(v); }
193  template<typename _Tp> static inline _Tp saturate(char v) { return _Tp(v); }
194  template<typename _Tp> static inline _Tp saturate(unsigned short v) { return _Tp(v); }
195  template<typename _Tp> static inline _Tp saturate(short v) { return _Tp(v); }
196  template<typename _Tp> static inline _Tp saturate(unsigned v) { return _Tp(v); }
197  template<typename _Tp> static inline _Tp saturate(int v) { return _Tp(v); }
198  template<typename _Tp> static inline _Tp saturate(float v) { return _Tp(v); }
199  template<typename _Tp> static inline _Tp saturate(double v) { return _Tp(v); }
200 
201  static double getMean(const std::vector<double> &v);
202  static double getMedian(const std::vector<double> &v);
203  static double getStdev(const std::vector<double> &v, const bool useBesselCorrection=false);
204 
205  static int modulo(const int a, const int n);
206 
207  private:
208  static const double ang_min_sinc;
209  static const double ang_min_mc;
210 };
211 
212 
213 
214 //Begining of the inline functions definition
215 
220 double vpMath::fact(unsigned int x)
221 {
222  if ( (x == 1) || (x == 0)) return 1;
223  return x * fact(x-1);
224 }
225 
234 long double vpMath::comb(unsigned int n, unsigned int p)
235 {
236  if (n == p) return 1;
237  return fact(n)/ (fact(n-p) * fact(p));
238 }
239 
240 
249 int vpMath::round(const double x)
250 {
251 #if defined(VISP_HAVE_FUNC_ROUND)
252  //:: to design the global namespace and avoid to call recursively vpMath::round
253  return (int)::round(x);
254 #elif defined(VISP_HAVE_FUNC_STD_ROUND)
255  return (int)std::round(x);
256 #else
257  return (x > 0.0) ? ((int) floor(x + 0.5)) : ((int) ceil(x - 0.5));
258 #endif
259 }
260 
267 int
268 #ifndef DOXYGEN_SHOULD_SKIP_THIS
269 (
270 #endif
272 #ifndef DOXYGEN_SHOULD_SKIP_THIS
273 )
274 #endif
275 (double x)
276 {
277  if (fabs(x) < std::numeric_limits<double>::epsilon())
278  return 0;
279  else {
280  if (x < 0)
281  return -1;
282  else
283  return 1;
284  }
285 }
286 
294 bool vpMath::nul(double x, double s)
295 {
296  return(fabs(x)<s);
297 }
298 
306 bool vpMath::equal(double x, double y, double s)
307 {
308  return( nul(x-y, s) );
309 }
310 
318 bool vpMath::greater(double x, double y, double s)
319 {
320  return(x>(y-s));
321 }
322 
333 double vpMath::sigmoid(double x, double x0,double x1, double n)
334 {
335  if(x < x0)
336  return 0.;
337  else if(x > x1)
338  return 1.;
339  double l0 = 1./(1.+exp(0.5*n));
340  double l1 = 1./(1.+exp(-0.5*n));
341  return (1./(1.+exp(-n*((x-x0)/(x1-x0)-0.5)))-l0)/(l1-l0);
342 }
343 
344 //unsigned char
345 template<> inline unsigned char vpMath::saturate<unsigned char>(char v) {
346  // On big endian arch like powerpc, char implementation is unsigned
347  // with CHAR_MIN=0, CHAR_MAX=255 and SCHAR_MIN=-128, SCHAR_MAX=127
348  // leading to (int)(char -127) = 129.
349  // On little endian arch, CHAR_MIN=-127 and CHAR_MAX=128 leading to
350  // (int)(char -127) = -127.
351  if (std::numeric_limits<char>::is_signed)
352  return (unsigned char) ((std::max)((int) v, 0));
353  else
354  return (unsigned char) ((unsigned int) v > SCHAR_MAX ? 0 : v);
355 }
356 
357 template<> inline unsigned char vpMath::saturate<unsigned char>(unsigned short v) {
358  return (unsigned char) (std::min)((unsigned int) v, (unsigned int) UCHAR_MAX);
359 }
360 
361 template<> inline unsigned char vpMath::saturate<unsigned char>(int v) {
362  return (unsigned char) ((unsigned int) v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0);
363 }
364 
365 template<> inline unsigned char vpMath::saturate<unsigned char>(short v) {
366  return saturate<unsigned char> ((int) v);
367 }
368 
369 template<> inline unsigned char vpMath::saturate<unsigned char>(unsigned int v) {
370  return (unsigned char) (std::min)(v, (unsigned int) UCHAR_MAX);
371 }
372 
373 template<> inline unsigned char vpMath::saturate<unsigned char>(float v) {
374  int iv = vpMath::round(v);
375  return saturate<unsigned char> (iv);
376 }
377 
378 template<> inline unsigned char vpMath::saturate<unsigned char>(double v) {
379  int iv = vpMath::round(v);
380  return saturate<unsigned char> (iv);
381 }
382 
383 //char
384 template<> inline char vpMath::saturate<char>(unsigned char v) {
385  return (char) (std::min)((int) v, SCHAR_MAX);
386 }
387 
388 template<> inline char vpMath::saturate<char>(unsigned short v) {
389  return (char) (std::min)((unsigned int) v, (unsigned int) SCHAR_MAX);
390 }
391 
392 template<> inline char vpMath::saturate<char>(int v) {
393  return (char) ((unsigned int) (v - SCHAR_MIN) <= (unsigned int) UCHAR_MAX ? v :
394  v > 0 ? SCHAR_MAX : SCHAR_MIN);
395 }
396 
397 template<> inline char vpMath::saturate<char>(short v) {
398  return saturate<char>((int) v);
399 }
400 
401 template<> inline char vpMath::saturate<char>(unsigned int v) {
402  return (char) (std::min)(v, (unsigned int) SCHAR_MAX);
403 }
404 
405 template<> inline char vpMath::saturate<char>(float v) {
406  int iv = vpMath::round(v);
407  return saturate<char>(iv);
408 }
409 
410 template<> inline char vpMath::saturate<char>(double v) {
411  int iv = vpMath::round(v);
412  return saturate<char>(iv);
413 }
414 
415 //unsigned short
416 template<> inline unsigned short vpMath::saturate<unsigned short>(char v) {
417  // On big endian arch like powerpc, char implementation is unsigned
418  // with CHAR_MIN=0, CHAR_MAX=255 and SCHAR_MIN=-128, SCHAR_MAX=127
419  // leading to (int)(char -127) = 129.
420  // On little endian arch, CHAR_MIN=-127 and CHAR_MAX=128 leading to
421  // (int)(char -127) = -127.
422  if (std::numeric_limits<char>::is_signed)
423  return (unsigned char) ((std::max)((int) v, 0));
424  else
425  return (unsigned char) ((unsigned int) v > SCHAR_MAX ? 0 : v);
426 }
427 
428 template<> inline unsigned short vpMath::saturate<unsigned short>(short v) {
429  return (unsigned short) (std::max)((int) v, 0);
430 }
431 
432 template<> inline unsigned short vpMath::saturate<unsigned short>(int v) {
433  return (unsigned short) ((unsigned int) v <= (unsigned int) USHRT_MAX ? v :
434  v > 0 ? USHRT_MAX : 0);
435 }
436 
437 template<> inline unsigned short vpMath::saturate<unsigned short>(unsigned int v) {
438  return (unsigned short) (std::min)(v, (unsigned int) USHRT_MAX);
439 }
440 
441 template<> inline unsigned short vpMath::saturate<unsigned short>(float v) {
442  int iv = vpMath::round(v);
443  return vpMath::saturate<unsigned short>(iv);
444 }
445 
446 template<> inline unsigned short vpMath::saturate<unsigned short>(double v) {
447  int iv = vpMath::round(v);
448  return vpMath::saturate<unsigned short>(iv);
449 }
450 
451 //short
452 template<> inline short vpMath::saturate<short>(unsigned short v) {
453  return (short) (std::min)((int) v, SHRT_MAX);
454 }
455 template<> inline short vpMath::saturate<short>(int v) {
456  return (short) ((unsigned int) (v - SHRT_MIN) <= (unsigned int) USHRT_MAX ? v :
457  v > 0 ? SHRT_MAX : SHRT_MIN);
458 }
459 template<> inline short vpMath::saturate<short>(unsigned int v) {
460  return (short) (std::min)(v, (unsigned int) SHRT_MAX);
461 }
462 template<> inline short vpMath::saturate<short>(float v) {
463  int iv = vpMath::round(v);
464  return vpMath::saturate<short>(iv);
465 }
466 template<> inline short vpMath::saturate<short>(double v) {
467  int iv = vpMath::round(v);
468  return vpMath::saturate<short>(iv);
469 }
470 
471 //int
472 template<> inline int vpMath::saturate<int>(float v) {
473  return vpMath::round(v);
474 }
475 
476 template<> inline int vpMath::saturate<int>(double v) {
477  return vpMath::round(v);
478 }
479 
480 //unsigned int
481 // (Comment from OpenCV) we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc.
482 template<> inline unsigned int vpMath::saturate<unsigned int>(float v) {
483  return (unsigned int) vpMath::round(v);
484 }
485 
486 template<> inline unsigned int vpMath::saturate<unsigned int>(double v) {
487  return (unsigned int) vpMath::round(v);
488 }
489 
490 #endif
static _Tp saturate(double v)
Definition: vpMath.h:199
static void swap(Type &a, Type &b)
Definition: vpMath.h:182
static _Tp saturate(char v)
Definition: vpMath.h:193
static double sigmoid(double x, double x0=0., double x1=1., double n=12.)
Definition: vpMath.h:333
static _Tp saturate(unsigned char v)
Definition: vpMath.h:192
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:306
Provides simple mathematics computation tools that are not available in the C mathematics library (ma...
Definition: vpMath.h:87
static _Tp saturate(unsigned short v)
Definition: vpMath.h:194
static double fact(unsigned int x)
Definition: vpMath.h:220
static int round(const double x)
Definition: vpMath.h:249
static Type abs(const Type &x)
Definition: vpMath.h:161
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:140
static _Tp saturate(short v)
Definition: vpMath.h:195
static bool nul(double x, double s=0.001)
Definition: vpMath.h:294
static double sqr(double x)
Definition: vpMath.h:110
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:151
static _Tp saturate(int v)
Definition: vpMath.h:197
static double rad(double deg)
Definition: vpMath.h:104
static _Tp saturate(unsigned v)
Definition: vpMath.h:196
static _Tp saturate(float v)
Definition: vpMath.h:198
static long double comb(unsigned int n, unsigned int p)
Definition: vpMath.h:234
static double deg(double rad)
Definition: vpMath.h:97
static bool greater(double x, double y, double s=0.001)
Definition: vpMath.h:318
static int() sign(double x)
Definition: vpMath.h:275