Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpMath.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  * Simple mathematical function not available in the C math library (math.h).
32  *
33  * Authors:
34  * Eric Marchand
35  *
36  *****************************************************************************/
37 
44 #include <stdint.h>
45 #include <numeric>
46 #include <functional>
47 #include <cmath>
48 
49 #include <visp3/core/vpMath.h>
50 #include <visp3/core/vpException.h>
51 
52 #if defined(VISP_HAVE_FUNC__ISNAN)
53 # include <float.h>
54 #endif
55 
56 #if !(defined(VISP_HAVE_FUNC_ISNAN) || defined(VISP_HAVE_FUNC_STD_ISNAN)) || !(defined(VISP_HAVE_FUNC_ISINF) || defined(VISP_HAVE_FUNC_STD_ISINF))
57 # if defined _MSC_VER || defined __BORLANDC__
58 typedef __int64 int64;
59 typedef unsigned __int64 uint64;
60 # else
61 typedef int64_t int64;
62 typedef uint64_t uint64;
63 # endif
64 
65 #ifndef DOXYGEN_SHOULD_SKIP_THIS
66 typedef union Cv64suf
67 {
68 // int64 i; //Unused variable, should be harmless to comment it
69  uint64 u;
70  double f;
71 }
72 Cv64suf;
73 #endif
74 #endif
75 
76 const double vpMath::ang_min_sinc = 1.0e-8;
77 const double vpMath::ang_min_mc = 2.5e-4;
78 
79 
85 bool vpMath::isNaN(const double value)
86 {
87 #if defined(VISP_HAVE_FUNC_ISNAN)
88  return isnan(value);
89 #elif defined(VISP_HAVE_FUNC_STD_ISNAN)
90  return std::isnan(value);
91 #elif defined(VISP_HAVE_FUNC__ISNAN)
92  return (_isnan(value) != 0);
93 #else
94  #if 0
95  //This trick should work for any compiler which claims to use IEEE floating point.
96  //Do not work with g++ and -ffast-math option.
97  return (value != value);
98  #else
99  //Taken from OpenCV source code CvIsNan()
100  Cv64suf ieee754;
101  ieee754.f = value;
102  return (((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
103  ((unsigned)ieee754.u != 0) > 0x7ff00000) != 0;
104  #endif
105 #endif
106 }
112 bool vpMath::isInf(const double value)
113 {
114 #if defined(VISP_HAVE_FUNC_ISINF)
115  return isinf(value);
116 #elif defined(VISP_HAVE_FUNC_STD_ISINF)
117  return std::isinf(value);
118 #elif defined(VISP_HAVE_FUNC__FINITE)
119  return !_finite(value);
120 #else
121  //Taken from OpenCV source code CvIsInf()
122  Cv64suf ieee754;
123  ieee754.f = value;
124  return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
125  (unsigned)ieee754.u == 0;
126 #endif
127 }
128 
138 double vpMath::mcosc(double cosx, double x)
139 {
140  if (fabs(x) < ang_min_mc) return 0.5 ;
141  else return ((1.0-cosx)/x/x) ;
142 }
143 
154 double vpMath::msinc(double sinx, double x)
155 {
156  if (fabs(x) < ang_min_mc) return (1./6.0) ;
157  else return ((1.0-sinx/x)/x/x) ;
158 }
159 
169 double vpMath::sinc(double x)
170 {
171  if (fabs(x) < ang_min_sinc) return 1.0 ;
172  else return sin(x)/x ;
173 }
184 double vpMath::sinc(double sinx, double x)
185 {
186  if (fabs(x) < ang_min_sinc) return 1.0 ;
187  else return (sinx/x) ;
188 }
189 
197 double vpMath::getMean(const std::vector<double> &v)
198 {
199  if(v.empty()) {
200  throw vpException(vpException::notInitialized, "Empty vector !");
201  }
202 
203  size_t size = v.size();
204 
205  double sum = std::accumulate(v.begin(), v.end(), 0.0);
206 
207  return sum / (double) size;
208 }
209 
217 double vpMath::getMedian(const std::vector<double> &v) {
218  if(v.empty()) {
219  throw vpException(vpException::notInitialized, "Empty vector !");
220  }
221 
222  double median = 0.0;
223  std::vector<double> v_copy = v;
224  size_t size = v_copy.size();
225 
226  if(size % 2 == 0) {
227  sort(v_copy.begin(), v_copy.end());
228  median = (v_copy[size / 2 - 1] + v_copy[size / 2]) / 2.0;
229  } else {
230  std::nth_element(v_copy.begin(), v_copy.begin() + (int) (size/2), v_copy.end());
231  median = v_copy[size/2];
232  }
233 
234  return median;
235 }
236 
245 double vpMath::getStdev(const std::vector<double> &v, const bool useBesselCorrection) {
246  if(v.empty()) {
247  throw vpException(vpException::notInitialized, "Empty vector !");
248  }
249 
250  double mean = getMean(v);
251 
252  std::vector<double> diff(v.size());
253  std::transform(v.begin(), v.end(), diff.begin(),
254  std::bind2nd(std::minus<double>(), mean));
255  double sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
256  double divisor = (double) v.size();
257  if(useBesselCorrection && v.size() > 1) {
258  divisor = divisor-1;
259  }
260 
261  return std::sqrt(sq_sum / divisor);
262 }
263 
274 int vpMath::modulo(const int a, const int n) {
275  return ((a % n) + n) % n;
276 }
static int modulo(const int a, const int n)
Definition: vpMath.cpp:274
static double getStdev(const std::vector< double > &v, const bool useBesselCorrection=false)
Definition: vpMath.cpp:245
static double getMedian(const std::vector< double > &v)
Definition: vpMath.cpp:217
static bool isNaN(const double value)
Definition: vpMath.cpp:85
error that can be emited by ViSP classes.
Definition: vpException.h:73
static bool isInf(const double value)
Definition: vpMath.cpp:112
static double sinc(double x)
Definition: vpMath.cpp:169
static double getMean(const std::vector< double > &v)
Definition: vpMath.cpp:197
static double mcosc(double cosx, double x)
Definition: vpMath.cpp:138
static double msinc(double sinx, double x)
Definition: vpMath.cpp:154