Visual Servoing Platform  version 3.0.0
vpMath.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 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 <visp3/core/vpMath.h>
48 #include <visp3/core/vpException.h>
49 
50 
51 #if defined(VISP_HAVE_FUNC__ISNAN)
52 # include <float.h>
53 #endif
54 
55 #if !(defined(VISP_HAVE_FUNC_ISNAN) || defined(VISP_HAVE_FUNC_STD_ISNAN)) || !(defined(VISP_HAVE_FUNC_ISINF) || defined(VISP_HAVE_FUNC_STD_ISINF))
56 # if defined _MSC_VER || defined __BORLANDC__
57 typedef __int64 int64;
58 typedef unsigned __int64 uint64;
59 # else
60 typedef int64_t int64;
61 typedef uint64_t uint64;
62 # endif
63 
64 #ifndef DOXYGEN_SHOULD_SKIP_THIS
65 typedef union Cv64suf
66 {
67  int64 i;
68  uint64 u;
69  double f;
70 }
71 Cv64suf;
72 #endif
73 #endif
74 
75 const double vpMath::ang_min_sinc = 1.0e-8;
76 const double vpMath::ang_min_mc = 2.5e-4;
77 
78 
84 bool vpMath::isNaN(const double value)
85 {
86 #if defined(VISP_HAVE_FUNC_ISNAN)
87  return isnan(value);
88 #elif defined(VISP_HAVE_FUNC_STD_ISNAN)
89  return std::isnan(value);
90 #elif defined(VISP_HAVE_FUNC__ISNAN)
91  return (_isnan(value) != 0);
92 #else
93  #if 0
94  //This trick should work for any compiler which claims to use IEEE floating point.
95  //Do not work with g++ and -ffast-math option.
96  return (value != value);
97  #else
98  //Taken from OpenCV source code CvIsNan()
99  Cv64suf ieee754;
100  ieee754.f = value;
101  return (((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
102  ((unsigned)ieee754.u != 0) > 0x7ff00000) != 0;
103  #endif
104 #endif
105 }
111 bool vpMath::isInf(const double value)
112 {
113 #if defined(VISP_HAVE_FUNC_ISINF)
114  return isinf(value);
115 #elif defined(VISP_HAVE_FUNC_STD_ISINF)
116  return std::isinf(value);
117 #elif defined(VISP_HAVE_FUNC__FINITE)
118  return !_finite(value);
119 #else
120  //Taken from OpenCV source code CvIsInf()
121  Cv64suf ieee754;
122  ieee754.f = value;
123  return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
124  (unsigned)ieee754.u == 0;
125 #endif
126 }
127 
137 double vpMath::mcosc(double cosx, double x)
138 {
139  if (fabs(x) < ang_min_mc) return 0.5 ;
140  else return ((1.0-cosx)/x/x) ;
141 }
142 
153 double vpMath::msinc(double sinx, double x)
154 {
155  if (fabs(x) < ang_min_mc) return (1./6.0) ;
156  else return ((1.0-sinx/x)/x/x) ;
157 }
158 
168 double vpMath::sinc(double x)
169 {
170  if (fabs(x) < ang_min_sinc) return 1.0 ;
171  else return sin(x)/x ;
172 }
183 double vpMath::sinc(double sinx, double x)
184 {
185  if (fabs(x) < ang_min_sinc) return 1.0 ;
186  else return (sinx/x) ;
187 }
188 
196 double vpMath::getMean(const std::vector<double> &v)
197 {
198  if(v.empty()) {
199  throw vpException(vpException::notInitialized, "Empty vector !");
200  }
201 
202  double sum = 0.0;
203  size_t size = v.size();
204 
205  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 }
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:84
error that can be emited by ViSP classes.
Definition: vpException.h:73
static bool isInf(const double value)
Definition: vpMath.cpp:111
static double sinc(double x)
Definition: vpMath.cpp:168
static double getMean(const std::vector< double > &v)
Definition: vpMath.cpp:196
static double mcosc(double cosx, double x)
Definition: vpMath.cpp:137
static double msinc(double sinx, double x)
Definition: vpMath.cpp:153