Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testMath.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  * Test some vpColVector functionalities.
32  *
33  * Authors:
34  * Souriya Trinh
35  *
36  *****************************************************************************/
37 
44 #include <iostream>
45 #include <limits>
46 #include <cfloat>
47 
48 #include <visp3/core/vpMath.h>
49 
50 #if defined _MSC_VER && _MSC_VER >= 1200
51  #pragma warning( disable: 4723 )
52 
53 // 4723 : potential divide by 0
54 #endif
55 
56 #ifdef WIN32
57  #ifndef NAN
58  //https://msdn.microsoft.com/en-us/library/w22adx1s%28v=vs.120%29.aspx
59  //http://tdistler.com/2011/03/24/how-to-define-nan-not-a-number-on-windows
60  static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
61  #define NAN (*(const float *) __nan)
62  #endif
63 #endif
64 
65 int main() {
66  //Test isNaN
67  if(vpMath::isNaN(0.0)) {
68  std::cerr << "Fail: IsNaN(0.0)=" << vpMath::isNaN(0.0) << " / should be false" << std::endl;
69  return -1;
70  }
71 
72  double num = 1.0, den = 0.0;
73  if(vpMath::isNaN(num/den)) {
74  std::cerr << "Fail: IsNaN(1.0/0.0)=" << vpMath::isNaN(num/den) << " / should be false" << std::endl;
75  return -1;
76  }
77 
78  if(!vpMath::isNaN(NAN)) {
79  std::cerr << "Fail: IsNaN(NAN)=" << vpMath::isNaN(NAN) << " / should be true" << std::endl;
80  return -1;
81  }
82 
83  num = 0.0;
84  if(!vpMath::isNaN(num/den)) {
85  std::cerr << "Fail: IsNaN(0.0/0.0)=" << vpMath::isNaN(num/den) << " / should be true" << std::endl;
86  return -1;
87  }
88 
89  if(!vpMath::isNaN(std::numeric_limits<double>::quiet_NaN())) {
90  std::cerr << "Fail: IsNaN(quiet_NaN)=" << vpMath::isNaN(std::numeric_limits<double>::quiet_NaN())
91  << " / should be true" << std::endl;
92  return -1;
93  }
94 
95  if(!vpMath::isNaN(std::numeric_limits<double>::signaling_NaN())) {
96  std::cerr << "Fail: IsNaN(signaling_NaN)=" << vpMath::isNaN(std::numeric_limits<double>::signaling_NaN())
97  << " / should be true" << std::endl;
98  return -1;
99  }
100 
101  if(vpMath::isNaN(std::numeric_limits<double>::infinity())) {
102  std::cerr << "Fail: IsNaN(infinity)=" << vpMath::isNaN(std::numeric_limits<double>::infinity())
103  << " / should be false" << std::endl;
104  return -1;
105  }
106 
107  if(vpMath::isNaN(1.0 / std::numeric_limits<double>::epsilon())) {
108  std::cerr << "Fail: IsNaN(1.0/epsilon)=" << vpMath::isNaN(1.0/std::numeric_limits<double>::epsilon())
109  << " / should be false" << std::endl;
110  return -1;
111  }
112 
113  if(!vpMath::isNaN(std::numeric_limits<double>::infinity() - std::numeric_limits<double>::infinity())) {
114  std::cerr << "Fail: IsNaN(1.0/epsilon)=" << vpMath::isNaN(1.0/std::numeric_limits<double>::epsilon())
115  << " / should be true" << std::endl;
116  return -1;
117  }
118 
119  float a = 0.0f, b = 0.0f;
120  if(!vpMath::isNaN(a/b)) {
121  std::cerr << "Fail: IsNaN(0.0f/0.0f)=" << vpMath::isNaN(a/b) << " / should be true" << std::endl;
122  return -1;
123  }
124  std::cout << "vpMath::isNaN is Ok !" << std::endl;
125 
126 
127  //Test isInf
128 #if !defined(VISP_HAVE_FUNC__FINITE)
129  //Disable this test if using _finite as (!_finite(NAN)) returns true whereas isinf(NAN) returns false
130  if(vpMath::isInf(NAN)) {
131  std::cerr << "Fail: vpMath::isInf(NAN)=" << vpMath::isInf(NAN) << " / should be false" << std::endl;
132  return -1;
133  }
134 #endif
135 
136  if(!vpMath::isInf(1.0/a)) {
137  std::cerr << "Fail: vpMath::isInf(1.0/0.0)=" << vpMath::isInf(1.0/a) << " / should be true" << std::endl;
138  return -1;
139  }
140 
141  if(vpMath::isInf(0.0)) {
142  std::cerr << "Fail: vpMath::isInf(0.0)=" << vpMath::isInf(0.0) << " / should be false" << std::endl;
143  return -1;
144  }
145 
146  if(!vpMath::isInf(exp(800.))) {
147  std::cerr << "Fail: vpMath::isInf(exp(800.))=" << vpMath::isInf(exp(800.)) << " / should be true" << std::endl;
148  return -1;
149  }
150 
151  if(vpMath::isInf(DBL_MIN/2.0)) {
152  std::cerr << "Fail: vpMath::isInf(DBL_MIN/2.0)=" << vpMath::isInf(DBL_MIN/2.0) << " / should be false" << std::endl;
153  return -1;
154  }
155  std::cout << "vpMath::isInf is Ok !" << std::endl;
156 
157 
158  //Test round
159  if(vpMath::round(2.3) != 2) {
160  std::cerr << "Fail: vpMath::round(2.3)=" << vpMath::round(2.3) << " / should be 2" << std::endl;
161  return -1;
162  }
163 
164  if(vpMath::round(3.8) != 4) {
165  std::cerr << "Fail: vpMath::round(3.8)=" << vpMath::round(3.8) << " / should be 4" << std::endl;
166  return -1;
167  }
168 
169  if(vpMath::round(5.5) != 6) {
170  std::cerr << "Fail: vpMath::round(5.5)=" << vpMath::round(5.5) << " / should be 6" << std::endl;
171  return -1;
172  }
173 
174  if(vpMath::round(-2.3) != -2) {
175  std::cerr << "Fail: vpMath::round(-2.3)=" << vpMath::round(-2.3) << " / should be -2" << std::endl;
176  return -1;
177  }
178 
179  if(vpMath::round(-3.8) != -4) {
180  std::cerr << "Fail: vpMath::round(-3.8)=" << vpMath::round(-3.8) << " / should be -4" << std::endl;
181  return -1;
182  }
183 
184  if(vpMath::round(-5.5) != -6) {
185  std::cerr << "Fail: vpMath::round(-5.5)=" << vpMath::round(-5.5) << " / should be -6" << std::endl;
186  return -1;
187  }
188 
189  if(vpMath::round(0.0) != 0) {
190  std::cerr << "Fail: vpMath::round(0.0)=" << vpMath::round(0.0) << " / should be 0" << std::endl;
191  return -1;
192  }
193  std::cout << "vpMath::round is Ok !" << std::endl;
194 
195 
196  //Test saturate functions
197  //unsigned char
198  char char_value = -127;
199  unsigned char uchar_value = vpMath::saturate<unsigned char>(char_value);
200  if(uchar_value != 0) {
201  std::cerr << "Fail: vpMath::saturate<unsigned char>(-127)=" << uchar_value << " / should be 0" << std::endl;
202  return -1;
203  }
204 
205  unsigned short ushort_value = 60000;
206  uchar_value = vpMath::saturate<unsigned char>(ushort_value);
207  if(uchar_value != UCHAR_MAX) {
208  std::cerr << "Fail: vpMath::saturate<unsigned char>(60000)=" << uchar_value << " / should be " << UCHAR_MAX << std::endl;
209  return -1;
210  }
211 
212  int int_value = 70000;
213  uchar_value = vpMath::saturate<unsigned char>(int_value);
214  if(uchar_value != UCHAR_MAX) {
215  std::cerr << "Fail: vpMath::saturate<unsigned char>(70000)=" << uchar_value << " / should be " << UCHAR_MAX << std::endl;
216  return -1;
217  }
218 
219  int_value = -70000;
220  uchar_value = vpMath::saturate<unsigned char>(int_value);
221  if(uchar_value != 0) {
222  std::cerr << "Fail: vpMath::saturate<unsigned char>(-70000)=" << uchar_value << " / should be 0" << std::endl;
223  return -1;
224  }
225 
226  short short_value = 30000;
227  uchar_value = vpMath::saturate<unsigned char>(short_value);
228  if(uchar_value != UCHAR_MAX) {
229  std::cerr << "Fail: vpMath::saturate<unsigned char>(30000)=" << uchar_value << " / should be " << UCHAR_MAX << std::endl;
230  return -1;
231  }
232 
233  short_value = -30000;
234  uchar_value = vpMath::saturate<unsigned char>(short_value);
235  if(uchar_value != 0) {
236  std::cerr << "Fail: vpMath::saturate<unsigned char>(-30000)=" << uchar_value << " / should be 0" << std::endl;
237  return -1;
238  }
239 
240  unsigned int uint_value = 10000;
241  uchar_value = vpMath::saturate<unsigned char>(uint_value);
242  if(uchar_value != UCHAR_MAX) {
243  std::cerr << "Fail: vpMath::saturate<unsigned char>(10000)=" << uchar_value << " / should be " << UCHAR_MAX << std::endl;
244  return -1;
245  }
246 
247  float float_value = 10000.1f;
248  uchar_value = vpMath::saturate<unsigned char>(float_value);
249  if(uchar_value != UCHAR_MAX) {
250  std::cerr << "Fail: vpMath::saturate<unsigned char>(10000.1f)=" << uchar_value << " / should be " << UCHAR_MAX << std::endl;
251  return -1;
252  }
253 
254  float_value = -10000.1f;
255  uchar_value = vpMath::saturate<unsigned char>(float_value);
256  if(uchar_value != 0) {
257  std::cerr << "Fail: vpMath::saturate<unsigned char>(-10000.1f)=" << uchar_value << " / should be 0" << std::endl;
258  return -1;
259  }
260 
261  double double_value = 10000.1;
262  uchar_value = vpMath::saturate<unsigned char>(double_value);
263  if(uchar_value != UCHAR_MAX) {
264  std::cerr << "Fail: vpMath::saturate<unsigned char>(10000.0)=" << uchar_value << " / should be " << UCHAR_MAX << std::endl;
265  return -1;
266  }
267 
268  double_value = -10000.1;
269  uchar_value = vpMath::saturate<unsigned char>(double_value);
270  if(uchar_value != 0) {
271  std::cerr << "Fail: vpMath::saturate<unsigned char>(-10000.0)=" << uchar_value << " / should be 0" << std::endl;
272  return -1;
273  }
274  std::cout << "vpMath::saturate<unsigned char>() is Ok !" << std::endl;
275 
276 
277  //char
278  uchar_value = 255;
279  char_value = vpMath::saturate<char>(uchar_value);
280  if(char_value != SCHAR_MAX) {
281  std::cerr << "Fail: vpMath::saturate<char>(255)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
282  return -1;
283  }
284 
285  ushort_value = 60000;
286  char_value = vpMath::saturate<char>(ushort_value);
287  if(char_value != SCHAR_MAX) {
288  std::cerr << "Fail: vpMath::saturate<char>(60000)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
289  return -1;
290  }
291 
292  int_value = 70000;
293  char_value = vpMath::saturate<char>(int_value);
294  if(char_value != SCHAR_MAX) {
295  std::cerr << "Fail: vpMath::saturate<char>(70000)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
296  return -1;
297  }
298 
299  int_value = -70000;
300  char_value = vpMath::saturate<char>(int_value);
301  if(char_value != (char)SCHAR_MIN) {
302  std::cerr << "Fail: vpMath::saturate<char>(-70000)=" << char_value << " / should be " << SCHAR_MIN << std::endl;
303  return -1;
304  }
305 
306  short_value = 30000;
307  char_value = vpMath::saturate<char>(short_value);
308  if(char_value != SCHAR_MAX) {
309  std::cerr << "Fail: vpMath::saturate<char>(30000)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
310  return -1;
311  }
312 
313  short_value = -30000;
314  char_value = vpMath::saturate<char>(short_value);
315  if(char_value != (char)SCHAR_MIN) {
316  std::cerr << "Fail: vpMath::saturate<char>(-30000)=" << char_value << " / should be " << SCHAR_MIN << std::endl;
317  return -1;
318  }
319 
320  uint_value = 10000;
321  char_value = vpMath::saturate<char>(uint_value);
322  if(char_value != SCHAR_MAX) {
323  std::cerr << "Fail: vpMath::saturate<char>(10000)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
324  return -1;
325  }
326 
327  float_value = 10000.1f;
328  char_value = vpMath::saturate<char>(float_value);
329  if(char_value != SCHAR_MAX) {
330  std::cerr << "Fail: vpMath::saturate<char>(10000.1f)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
331  return -1;
332  }
333 
334  float_value = -10000.1f;
335  char_value = vpMath::saturate<char>(float_value);
336  if(char_value != (char)SCHAR_MIN) {
337  std::cerr << "Fail: vpMath::saturate<char>(-10000.1f)=" << char_value << " / should be " << SCHAR_MIN << std::endl;
338  return -1;
339  }
340 
341  double_value = 10000.1;
342  char_value = vpMath::saturate<char>(double_value);
343  if(char_value != SCHAR_MAX) {
344  std::cerr << "Fail: vpMath::saturate<char>(10000.1)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
345  return -1;
346  }
347 
348  double_value = -10000.1;
349  char_value = vpMath::saturate<char>(double_value);
350  if(char_value != (char)SCHAR_MIN) {
351  std::cerr << "Fail: vpMath::saturate<char>(-10000.1)=" << char_value << " / should be " << SCHAR_MIN << std::endl;
352  return -1;
353  }
354  std::cout << "vpMath::saturate<char>() is Ok !" << std::endl;
355 
356 
357  //unsigned short
358  char_value = -127;
359  ushort_value = vpMath::saturate<unsigned short>(char_value);
360  if(ushort_value != 0) {
361  std::cerr << "Fail: vpMath::saturate<unsigned short>(-127)=" << ushort_value << " / should be 0" << std::endl;
362  return -1;
363  }
364 
365  short_value = -30000;
366  ushort_value = vpMath::saturate<unsigned short>(short_value);
367  if(ushort_value != 0) {
368  std::cerr << "Fail: vpMath::saturate<unsigned short>(-30000)=" << ushort_value << " / should be 0" << std::endl;
369  return -1;
370  }
371 
372  int_value = 70000;
373  ushort_value = vpMath::saturate<unsigned short>(int_value);
374  if(ushort_value != USHRT_MAX) {
375  std::cerr << "Fail: vpMath::saturate<unsigned short>(70000)=" << ushort_value << " / should be " << USHRT_MAX << std::endl;
376  return -1;
377  }
378 
379  int_value = -70000;
380  ushort_value = vpMath::saturate<unsigned short>(int_value);
381  if(ushort_value != 0) {
382  std::cerr << "Fail: vpMath::saturate<unsigned short>(-70000)=" << ushort_value << " / should be 0" << std::endl;
383  return -1;
384  }
385 
386  uint_value = 70000;
387  ushort_value = vpMath::saturate<unsigned short>(uint_value);
388  if(ushort_value != USHRT_MAX) {
389  std::cerr << "Fail: vpMath::saturate<unsigned short>(70000)=" << ushort_value << " / should be " << USHRT_MAX << std::endl;
390  return -1;
391  }
392 
393  float_value = 70000.1f;
394  ushort_value = vpMath::saturate<unsigned short>(float_value);
395  if(ushort_value != USHRT_MAX) {
396  std::cerr << "Fail: vpMath::saturate<unsigned short>(70000.1f)=" << ushort_value << " / should be " << USHRT_MAX << std::endl;
397  return -1;
398  }
399 
400  float_value = -10000.1f;
401  ushort_value = vpMath::saturate<unsigned short>(float_value);
402  if(ushort_value != 0) {
403  std::cerr << "Fail: vpMath::saturate<unsigned short>(-10000.1f)=" << ushort_value << " / should be 0" << std::endl;
404  return -1;
405  }
406 
407  double_value = 70000.1;
408  ushort_value = vpMath::saturate<unsigned short>(double_value);
409  if(ushort_value != USHRT_MAX) {
410  std::cerr << "Fail: vpMath::saturate<unsigned short>(70000.1)=" << ushort_value << " / should be " << USHRT_MAX << std::endl;
411  return -1;
412  }
413 
414  double_value = -10000.1;
415  ushort_value = vpMath::saturate<unsigned short>(double_value);
416  if(ushort_value != 0) {
417  std::cerr << "Fail: vpMath::saturate<unsigned short>(-10000.1)=" << ushort_value << " / should be 0" << std::endl;
418  return -1;
419  }
420  std::cout << "vpMath::saturate<unsigned short>() is Ok !" << std::endl;
421 
422 
423  //short
424  ushort_value = 60000;
425  short_value = vpMath::saturate<short>(ushort_value);
426  if(short_value != SHRT_MAX) {
427  std::cerr << "Fail: vpMath::saturate<short>(60000)=" << short_value << " / should be " << SHRT_MAX << std::endl;
428  return -1;
429  }
430 
431  int_value = 70000;
432  short_value = vpMath::saturate<short>(int_value);
433  if(short_value != SHRT_MAX) {
434  std::cerr << "Fail: vpMath::saturate<short>(70000)=" << short_value << " / should be " << SHRT_MAX << std::endl;
435  return -1;
436  }
437 
438  int_value = -70000;
439  short_value = vpMath::saturate<short>(int_value);
440  if(short_value != SHRT_MIN) {
441  std::cerr << "Fail: vpMath::saturate<short>(-70000)=" << short_value << " / should be " << SHRT_MIN << std::endl;
442  return -1;
443  }
444 
445  uint_value = 70000;
446  short_value = vpMath::saturate<short>(uint_value);
447  if(short_value != SHRT_MAX) {
448  std::cerr << "Fail: vpMath::saturate<short>(70000)=" << short_value << " / should be " << SHRT_MAX << std::endl;
449  return -1;
450  }
451 
452  float_value = 70000.1f;
453  short_value = vpMath::saturate<short>(float_value);
454  if(short_value != SHRT_MAX) {
455  std::cerr << "Fail: vpMath::saturate<short>(70000.1f)=" << short_value << " / should be " << SHRT_MAX << std::endl;
456  return -1;
457  }
458 
459  float_value = -70000.1f;
460  short_value = vpMath::saturate<short>(float_value);
461  if(short_value != SHRT_MIN) {
462  std::cerr << "Fail: vpMath::saturate<short>(-70000.1f)=" << short_value << " / should be " << SHRT_MIN << std::endl;
463  return -1;
464  }
465 
466  double_value = 70000.1;
467  short_value = vpMath::saturate<short>(double_value);
468  if(short_value != SHRT_MAX) {
469  std::cerr << "Fail: vpMath::saturate<short>(70000.1)=" << short_value << " / should be " << SHRT_MAX << std::endl;
470  return -1;
471  }
472 
473  double_value = -70000.1;
474  short_value = vpMath::saturate<short>(double_value);
475  if(short_value != SHRT_MIN) {
476  std::cerr << "Fail: vpMath::saturate<short>(70000.1)=" << short_value << " / should be " << SHRT_MIN << std::endl;
477  return -1;
478  }
479  std::cout << "vpMath::saturate<short>() is Ok !" << std::endl;
480 
481 
482  //Test mean, median and standard deviation against Matlab with rng(0) and rand(10,1)*10
483  std::vector<double> vectorOfDoubles(10);
484  vectorOfDoubles[0] = 8.1472;
485  vectorOfDoubles[1] = 9.0579;
486  vectorOfDoubles[2] = 1.2699;
487  vectorOfDoubles[3] = 9.1338;
488  vectorOfDoubles[4] = 6.3236;
489  vectorOfDoubles[5] = 0.9754;
490  vectorOfDoubles[6] = 2.7850;
491  vectorOfDoubles[7] = 5.4688;
492  vectorOfDoubles[8] = 9.5751;
493  vectorOfDoubles[9] = 9.6489;
494 
495 
496  double res = vpMath::getMean(vectorOfDoubles);
497  if(!vpMath::equal(res, 6.2386, 0.001)) {
498  std::cerr << "Problem with vpMath::getMean()=" << res << std::endl;
499  return -1;
500  }
501  std::cout << "vpMath::getMean() is Ok !" << std::endl;
502 
503  res = vpMath::getStdev(vectorOfDoubles);
504  if(!vpMath::equal(res, 3.2810, 0.001)) {
505  std::cerr << "Problem with vpMath::getStdev()=" << res << std::endl;
506  return -1;
507  }
508 
509  res = vpMath::getStdev(vectorOfDoubles, true);
510  if(!vpMath::equal(res, 3.4585, 0.001)) {
511  std::cerr << "Problem with vpMath::getStdev() with Bessel correction=" << res << std::endl;
512  return -1;
513  }
514  std::cout << "vpMath::getStdev() is Ok !" << std::endl;
515 
516  res = vpMath::getMedian(vectorOfDoubles);
517  if(!vpMath::equal(res, 7.2354, 0.001)) {
518  std::cerr << "Problem with vpMath::getMedian()=" << res << std::endl;
519  return -1;
520  }
521 
522  //Test median with odd number of elements
523  vectorOfDoubles.push_back(1.5761);
524  res = vpMath::getMedian(vectorOfDoubles);
525  if(!vpMath::equal(res, 6.3236, 0.001)) {
526  std::cerr << "Problem with vpMath::getMedian()=" << res << std::endl;
527  return -1;
528  }
529  std::cout << "vpMath::getMedian() is Ok !" << std::endl;
530 
531 
532  std::cout << "OK !" << std::endl;
533  return 0;
534 }
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
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:306
static bool isInf(const double value)
Definition: vpMath.cpp:112
static int round(const double x)
Definition: vpMath.h:249
static double getMean(const std::vector< double > &v)
Definition: vpMath.cpp:197