Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
testMath.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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 https://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 core functionalities.
32 */
33
39
40#include <cfloat>
41#include <iostream>
42#include <limits>
43
44#include <visp3/core/vpMath.h>
45#include <visp3/core/vpColVector.h>
46#include <visp3/core/vpRxyzVector.h>
47
48#include <visp3/core/vpHomogeneousMatrix.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
60static const unsigned long __nan[2] = { 0xffffffff, 0x7fffffff };
61#define NAN (*(const float *)__nan)
62#endif
63#endif
64
65int main()
66{
67#ifdef ENABLE_VISP_NAMESPACE
68 using namespace VISP_NAMESPACE_NAME;
69#endif
70
71#if !defined(VISP_HAVE_FAST_MATH)
72 // Test isNaN
73 if (vpMath::isNaN(0.0)) {
74 std::cerr << "Fail: IsNaN(0.0)=" << vpMath::isNaN(0.0) << " / should be false" << std::endl;
75 return EXIT_FAILURE;
76 }
77
78 double num = 1.0, den = 0.0;
79 if (vpMath::isNaN(num / den)) {
80 std::cerr << "Fail: IsNaN(1.0/0.0)=" << vpMath::isNaN(num / den) << " / should be false" << std::endl;
81 return EXIT_FAILURE;
82 }
83
84 if (!vpMath::isNaN(NAN)) {
85 std::cerr << "Fail: IsNaN(NAN)=" << vpMath::isNaN(NAN) << " / should be true" << std::endl;
86 return EXIT_FAILURE;
87 }
88
89 num = 0.0;
90 if (!vpMath::isNaN(num / den)) {
91 std::cerr << "Fail: IsNaN(0.0/0.0)=" << vpMath::isNaN(num / den) << " / should be true" << std::endl;
92 return EXIT_FAILURE;
93 }
94
95 if (!vpMath::isNaN(std::numeric_limits<double>::quiet_NaN())) {
96 std::cerr << "Fail: IsNaN(quiet_NaN)=" << vpMath::isNaN(std::numeric_limits<double>::quiet_NaN())
97 << " / should be true" << std::endl;
98 return EXIT_FAILURE;
99 }
100
101 if (!vpMath::isNaN(std::numeric_limits<float>::quiet_NaN())) {
102 std::cerr << "Fail: IsNaN(quiet_NaN)=" << vpMath::isNaN(std::numeric_limits<float>::quiet_NaN())
103 << " / should be true" << std::endl;
104 return EXIT_FAILURE;
105 }
106
107 if (!vpMath::isNaN(std::numeric_limits<double>::signaling_NaN())) {
108 std::cerr << "Fail: IsNaN(signaling_NaN)=" << vpMath::isNaN(std::numeric_limits<double>::signaling_NaN())
109 << " / should be true" << std::endl;
110 return EXIT_FAILURE;
111 }
112
113 if (!vpMath::isNaN(std::numeric_limits<float>::signaling_NaN())) {
114 std::cerr << "Fail: IsNaN(signaling_NaN)=" << vpMath::isNaN(std::numeric_limits<float>::signaling_NaN())
115 << " / should be true" << std::endl;
116 return EXIT_FAILURE;
117 }
118
119 if (vpMath::isNaN(std::numeric_limits<double>::infinity())) {
120 std::cerr << "Fail: IsNaN(infinity)=" << vpMath::isNaN(std::numeric_limits<double>::infinity())
121 << " / should be false" << std::endl;
122 return EXIT_FAILURE;
123 }
124
125 if (vpMath::isNaN(std::numeric_limits<float>::infinity())) {
126 std::cerr << "Fail: IsNaN(infinity)=" << vpMath::isNaN(std::numeric_limits<float>::infinity())
127 << " / should be false" << std::endl;
128 return EXIT_FAILURE;
129 }
130
131 if (vpMath::isNaN(1.0 / std::numeric_limits<double>::epsilon())) {
132 std::cerr << "Fail: IsNaN(1.0/epsilon)=" << vpMath::isNaN(1.0 / std::numeric_limits<double>::epsilon())
133 << " / should be false" << std::endl;
134 return EXIT_FAILURE;
135 }
136
137 if (!vpMath::isNaN(std::numeric_limits<double>::infinity() - std::numeric_limits<double>::infinity())) {
138 std::cerr << "Fail: IsNaN(infinity - infinity)="
139 << vpMath::isNaN(std::numeric_limits<double>::infinity() - std::numeric_limits<double>::infinity())
140 << " / should be true" << std::endl;
141 return EXIT_FAILURE;
142 }
143
144 float a = 0.0f, b = 0.0f;
145 if (!vpMath::isNaN(a / b)) {
146 std::cerr << "Fail: IsNaN(0.0f/0.0f)=" << vpMath::isNaN(a / b) << " / should be true" << std::endl;
147 return EXIT_FAILURE;
148 }
149 std::cout << "vpMath::isNaN is Ok !" << std::endl;
150
151 // Test isInf
152 if (vpMath::isInf(NAN)) {
153 std::cerr << "Fail: vpMath::isInf(NAN)=" << vpMath::isInf(NAN) << " / should be false" << std::endl;
154 return EXIT_FAILURE;
155 }
156
157 if (!vpMath::isInf(1.0 / a)) {
158 std::cerr << "Fail: vpMath::isInf(1.0/0.0)=" << vpMath::isInf(1.0 / a) << " / should be true" << std::endl;
159 return EXIT_FAILURE;
160 }
161
162 if (vpMath::isInf(0.0)) {
163 std::cerr << "Fail: vpMath::isInf(0.0)=" << vpMath::isInf(0.0) << " / should be false" << std::endl;
164 return EXIT_FAILURE;
165 }
166
167 if (!vpMath::isInf(exp(800.))) {
168 std::cerr << "Fail: vpMath::isInf(exp(800.))=" << vpMath::isInf(exp(800.)) << " / should be true" << std::endl;
169 return EXIT_FAILURE;
170 }
171
172 if (vpMath::isInf(DBL_MIN / 2.0)) {
173 std::cerr << "Fail: vpMath::isInf(DBL_MIN/2.0)=" << vpMath::isInf(DBL_MIN / 2.0) << " / should be false"
174 << std::endl;
175 return EXIT_FAILURE;
176 }
177 std::cout << "vpMath::isInf is Ok !" << std::endl;
178
179 // Test isfinite
180 if (vpMath::isFinite(NAN)) {
181 std::cerr << "Fail: vpMath::isFinite(NAN)=" << vpMath::isFinite(NAN) << " / should be false" << std::endl;
182 return EXIT_FAILURE;
183 }
184
185 if (vpMath::isFinite(1.0 / a)) {
186 std::cerr << "Fail: vpMath::isFinite(1.0/0.0)=" << vpMath::isFinite(1.0 / a) << " / should be false" << std::endl;
187 return EXIT_FAILURE;
188 }
189
190 if (vpMath::isFinite(exp(800.))) {
191 std::cerr << "Fail: vpMath::isFinite(exp(800.))=" << vpMath::isFinite(exp(800.)) << " / should be false" << std::endl;
192 return EXIT_FAILURE;
193 }
194#endif
195
196 if (!vpMath::isFinite(0.0)) {
197 std::cerr << "Fail: vpMath::isFinite(0.0)=" << vpMath::isFinite(0.0) << " / should be true" << std::endl;
198 return EXIT_FAILURE;
199 }
200
201 if (!vpMath::isFinite(DBL_MIN / 2.0)) {
202 std::cerr << "Fail: vpMath::isFinite(DBL_MIN/2.0)=" << vpMath::isFinite(DBL_MIN / 2.0) << " / should be true"
203 << std::endl;
204 return EXIT_FAILURE;
205 }
206
207 if (!vpMath::isFinite(std::numeric_limits<float>::max())) {
208 std::cerr << "Fail: vpMath::isFinite(DBL_MAX)=" << vpMath::isFinite(std::numeric_limits<float>::max()) << " / should be true"
209 << std::endl;
210 return EXIT_FAILURE;
211 }
212 std::cout << "vpMath::isFinite is Ok !" << std::endl;
213
214 // Test isNumber
215 if (!vpMath::isNumber("123")) {
216 std::cerr << "Fail: vpMath::isNumber(\"123\")=" << vpMath::isNumber("123") << " / should be false" << std::endl;
217 return EXIT_FAILURE;
218 }
219 if (vpMath::isNumber("string")) {
220 std::cerr << "Fail: vpMath::isNumber(\"string\")=" << vpMath::isNumber("string") << " / should be true" << std::endl;
221 return EXIT_FAILURE;
222 }
223 if (vpMath::isNumber("123string")) {
224 std::cerr << "Fail: vpMath::isNumber(\"123string\")=" << vpMath::isNumber("123string") << " / should be true" << std::endl;
225 return EXIT_FAILURE;
226 }
227 std::cout << "vpMath::isNumber is Ok !" << std::endl;
228
229 // Test round
230 if (vpMath::round(2.3) != 2) {
231 std::cerr << "Fail: vpMath::round(2.3)=" << vpMath::round(2.3) << " / should be 2" << std::endl;
232 return EXIT_FAILURE;
233 }
234
235 if (vpMath::round(3.8) != 4) {
236 std::cerr << "Fail: vpMath::round(3.8)=" << vpMath::round(3.8) << " / should be 4" << std::endl;
237 return EXIT_FAILURE;
238 }
239
240 if (vpMath::round(5.5) != 6) {
241 std::cerr << "Fail: vpMath::round(5.5)=" << vpMath::round(5.5) << " / should be 6" << std::endl;
242 return EXIT_FAILURE;
243 }
244
245 if (vpMath::round(-2.3) != -2) {
246 std::cerr << "Fail: vpMath::round(-2.3)=" << vpMath::round(-2.3) << " / should be -2" << std::endl;
247 return EXIT_FAILURE;
248 }
249
250 if (vpMath::round(-3.8) != -4) {
251 std::cerr << "Fail: vpMath::round(-3.8)=" << vpMath::round(-3.8) << " / should be -4" << std::endl;
252 return EXIT_FAILURE;
253 }
254
255 if (vpMath::round(-5.5) != -6) {
256 std::cerr << "Fail: vpMath::round(-5.5)=" << vpMath::round(-5.5) << " / should be -6" << std::endl;
257 return EXIT_FAILURE;
258 }
259
260 if (vpMath::round(0.0) != 0) {
261 std::cerr << "Fail: vpMath::round(0.0)=" << vpMath::round(0.0) << " / should be 0" << std::endl;
262 return EXIT_FAILURE;
263 }
264 std::cout << "vpMath::round is Ok !" << std::endl;
265
266 // Test saturate functions
267 // unsigned char
268 char char_value = -127;
269 unsigned char uchar_value = vpMath::saturate<unsigned char>(char_value);
270 if (uchar_value != 0) {
271 std::cerr << "Fail: vpMath::saturate<unsigned char>(-127)=" << uchar_value << " / should be 0" << std::endl;
272 return EXIT_FAILURE;
273 }
274
275 unsigned short ushort_value = 60000;
276 uchar_value = vpMath::saturate<unsigned char>(ushort_value);
277 if (uchar_value != UCHAR_MAX) {
278 std::cerr << "Fail: vpMath::saturate<unsigned char>(60000)=" << uchar_value << " / should be " << UCHAR_MAX
279 << std::endl;
280 return EXIT_FAILURE;
281 }
282
283 int int_value = 70000;
284 uchar_value = vpMath::saturate<unsigned char>(int_value);
285 if (uchar_value != UCHAR_MAX) {
286 std::cerr << "Fail: vpMath::saturate<unsigned char>(70000)=" << uchar_value << " / should be " << UCHAR_MAX
287 << std::endl;
288 return EXIT_FAILURE;
289 }
290
291 int_value = -70000;
292 uchar_value = vpMath::saturate<unsigned char>(int_value);
293 if (uchar_value != 0) {
294 std::cerr << "Fail: vpMath::saturate<unsigned char>(-70000)=" << uchar_value << " / should be 0" << std::endl;
295 return EXIT_FAILURE;
296 }
297
298 short short_value = 30000;
299 uchar_value = vpMath::saturate<unsigned char>(short_value);
300 if (uchar_value != UCHAR_MAX) {
301 std::cerr << "Fail: vpMath::saturate<unsigned char>(30000)=" << uchar_value << " / should be " << UCHAR_MAX
302 << std::endl;
303 return EXIT_FAILURE;
304 }
305
306 short_value = -30000;
307 uchar_value = vpMath::saturate<unsigned char>(short_value);
308 if (uchar_value != 0) {
309 std::cerr << "Fail: vpMath::saturate<unsigned char>(-30000)=" << uchar_value << " / should be 0" << std::endl;
310 return EXIT_FAILURE;
311 }
312
313 unsigned int uint_value = 10000;
314 uchar_value = vpMath::saturate<unsigned char>(uint_value);
315 if (uchar_value != UCHAR_MAX) {
316 std::cerr << "Fail: vpMath::saturate<unsigned char>(10000)=" << uchar_value << " / should be " << UCHAR_MAX
317 << std::endl;
318 return EXIT_FAILURE;
319 }
320
321 float float_value = 10000.1f;
322 uchar_value = vpMath::saturate<unsigned char>(float_value);
323 if (uchar_value != UCHAR_MAX) {
324 std::cerr << "Fail: vpMath::saturate<unsigned char>(10000.1f)=" << uchar_value << " / should be " << UCHAR_MAX
325 << std::endl;
326 return EXIT_FAILURE;
327 }
328
329 float_value = -10000.1f;
330 uchar_value = vpMath::saturate<unsigned char>(float_value);
331 if (uchar_value != 0) {
332 std::cerr << "Fail: vpMath::saturate<unsigned char>(-10000.1f)=" << uchar_value << " / should be 0" << std::endl;
333 return EXIT_FAILURE;
334 }
335
336 double double_value = 10000.1;
337 uchar_value = vpMath::saturate<unsigned char>(double_value);
338 if (uchar_value != UCHAR_MAX) {
339 std::cerr << "Fail: vpMath::saturate<unsigned char>(10000.0)=" << uchar_value << " / should be " << UCHAR_MAX
340 << std::endl;
341 return EXIT_FAILURE;
342 }
343
344 double_value = -10000.1;
345 uchar_value = vpMath::saturate<unsigned char>(double_value);
346 if (uchar_value != 0) {
347 std::cerr << "Fail: vpMath::saturate<unsigned char>(-10000.0)=" << uchar_value << " / should be 0" << std::endl;
348 return EXIT_FAILURE;
349 }
350 std::cout << "vpMath::saturate<unsigned char>() is Ok !" << std::endl;
351
352 // char
353 uchar_value = 255;
354 char_value = vpMath::saturate<char>(uchar_value);
355 if (char_value != SCHAR_MAX) {
356 std::cerr << "Fail: vpMath::saturate<char>(255)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
357 return EXIT_FAILURE;
358 }
359
360 ushort_value = 60000;
361 char_value = vpMath::saturate<char>(ushort_value);
362 if (char_value != SCHAR_MAX) {
363 std::cerr << "Fail: vpMath::saturate<char>(60000)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
364 return EXIT_FAILURE;
365 }
366
367 int_value = 70000;
368 char_value = vpMath::saturate<char>(int_value);
369 if (char_value != SCHAR_MAX) {
370 std::cerr << "Fail: vpMath::saturate<char>(70000)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
371 return EXIT_FAILURE;
372 }
373
374 int_value = -70000;
375 char_value = vpMath::saturate<char>(int_value);
376 if (char_value != static_cast<char>(SCHAR_MIN)) {
377 std::cerr << "Fail: vpMath::saturate<char>(-70000)=" << char_value << " / should be " << SCHAR_MIN << std::endl;
378 return EXIT_FAILURE;
379 }
380
381 short_value = 30000;
382 char_value = vpMath::saturate<char>(short_value);
383 if (char_value != SCHAR_MAX) {
384 std::cerr << "Fail: vpMath::saturate<char>(30000)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
385 return EXIT_FAILURE;
386 }
387
388 short_value = -30000;
389 char_value = vpMath::saturate<char>(short_value);
390 if (char_value != static_cast<char>(SCHAR_MIN)) {
391 std::cerr << "Fail: vpMath::saturate<char>(-30000)=" << char_value << " / should be " << SCHAR_MIN << std::endl;
392 return EXIT_FAILURE;
393 }
394
395 uint_value = 10000;
396 char_value = vpMath::saturate<char>(uint_value);
397 if (char_value != SCHAR_MAX) {
398 std::cerr << "Fail: vpMath::saturate<char>(10000)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
399 return EXIT_FAILURE;
400 }
401
402 float_value = 10000.1f;
403 char_value = vpMath::saturate<char>(float_value);
404 if (char_value != SCHAR_MAX) {
405 std::cerr << "Fail: vpMath::saturate<char>(10000.1f)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
406 return EXIT_FAILURE;
407 }
408
409 float_value = -10000.1f;
410 char_value = vpMath::saturate<char>(float_value);
411 if (char_value != static_cast<char>(SCHAR_MIN)) {
412 std::cerr << "Fail: vpMath::saturate<char>(-10000.1f)=" << char_value << " / should be " << SCHAR_MIN << std::endl;
413 return EXIT_FAILURE;
414 }
415
416 double_value = 10000.1;
417 char_value = vpMath::saturate<char>(double_value);
418 if (char_value != SCHAR_MAX) {
419 std::cerr << "Fail: vpMath::saturate<char>(10000.1)=" << char_value << " / should be " << SCHAR_MAX << std::endl;
420 return EXIT_FAILURE;
421 }
422
423 double_value = -10000.1;
424 char_value = vpMath::saturate<char>(double_value);
425 if (char_value != static_cast<char>(SCHAR_MIN)) {
426 std::cerr << "Fail: vpMath::saturate<char>(-10000.1)=" << char_value << " / should be " << SCHAR_MIN << std::endl;
427 return EXIT_FAILURE;
428 }
429 std::cout << "vpMath::saturate<char>() is Ok !" << std::endl;
430
431 // unsigned short
432 char_value = -127;
433 ushort_value = vpMath::saturate<unsigned short>(char_value);
434 if (ushort_value != 0) {
435 std::cerr << "Fail: vpMath::saturate<unsigned short>(-127)=" << ushort_value << " / should be 0" << std::endl;
436 return EXIT_FAILURE;
437 }
438
439 short_value = -30000;
440 ushort_value = vpMath::saturate<unsigned short>(short_value);
441 if (ushort_value != 0) {
442 std::cerr << "Fail: vpMath::saturate<unsigned short>(-30000)=" << ushort_value << " / should be 0" << std::endl;
443 return EXIT_FAILURE;
444 }
445
446 int_value = 70000;
447 ushort_value = vpMath::saturate<unsigned short>(int_value);
448 if (ushort_value != USHRT_MAX) {
449 std::cerr << "Fail: vpMath::saturate<unsigned short>(70000)=" << ushort_value << " / should be " << USHRT_MAX
450 << std::endl;
451 return EXIT_FAILURE;
452 }
453
454 int_value = -70000;
455 ushort_value = vpMath::saturate<unsigned short>(int_value);
456 if (ushort_value != 0) {
457 std::cerr << "Fail: vpMath::saturate<unsigned short>(-70000)=" << ushort_value << " / should be 0" << std::endl;
458 return EXIT_FAILURE;
459 }
460
461 uint_value = 70000;
462 ushort_value = vpMath::saturate<unsigned short>(uint_value);
463 if (ushort_value != USHRT_MAX) {
464 std::cerr << "Fail: vpMath::saturate<unsigned short>(70000)=" << ushort_value << " / should be " << USHRT_MAX
465 << std::endl;
466 return EXIT_FAILURE;
467 }
468
469 float_value = 70000.1f;
470 ushort_value = vpMath::saturate<unsigned short>(float_value);
471 if (ushort_value != USHRT_MAX) {
472 std::cerr << "Fail: vpMath::saturate<unsigned short>(70000.1f)=" << ushort_value << " / should be " << USHRT_MAX
473 << std::endl;
474 return EXIT_FAILURE;
475 }
476
477 float_value = -10000.1f;
478 ushort_value = vpMath::saturate<unsigned short>(float_value);
479 if (ushort_value != 0) {
480 std::cerr << "Fail: vpMath::saturate<unsigned short>(-10000.1f)=" << ushort_value << " / should be 0" << std::endl;
481 return EXIT_FAILURE;
482 }
483
484 double_value = 70000.1;
485 ushort_value = vpMath::saturate<unsigned short>(double_value);
486 if (ushort_value != USHRT_MAX) {
487 std::cerr << "Fail: vpMath::saturate<unsigned short>(70000.1)=" << ushort_value << " / should be " << USHRT_MAX
488 << std::endl;
489 return EXIT_FAILURE;
490 }
491
492 double_value = -10000.1;
493 ushort_value = vpMath::saturate<unsigned short>(double_value);
494 if (ushort_value != 0) {
495 std::cerr << "Fail: vpMath::saturate<unsigned short>(-10000.1)=" << ushort_value << " / should be 0" << std::endl;
496 return EXIT_FAILURE;
497 }
498 std::cout << "vpMath::saturate<unsigned short>() is Ok !" << std::endl;
499
500 // short
501 ushort_value = 60000;
502 short_value = vpMath::saturate<short>(ushort_value);
503 if (short_value != SHRT_MAX) {
504 std::cerr << "Fail: vpMath::saturate<short>(60000)=" << short_value << " / should be " << SHRT_MAX << std::endl;
505 return EXIT_FAILURE;
506 }
507
508 int_value = 70000;
509 short_value = vpMath::saturate<short>(int_value);
510 if (short_value != SHRT_MAX) {
511 std::cerr << "Fail: vpMath::saturate<short>(70000)=" << short_value << " / should be " << SHRT_MAX << std::endl;
512 return EXIT_FAILURE;
513 }
514
515 int_value = -70000;
516 short_value = vpMath::saturate<short>(int_value);
517 if (short_value != SHRT_MIN) {
518 std::cerr << "Fail: vpMath::saturate<short>(-70000)=" << short_value << " / should be " << SHRT_MIN << std::endl;
519 return EXIT_FAILURE;
520 }
521
522 uint_value = 70000;
523 short_value = vpMath::saturate<short>(uint_value);
524 if (short_value != SHRT_MAX) {
525 std::cerr << "Fail: vpMath::saturate<short>(70000)=" << short_value << " / should be " << SHRT_MAX << std::endl;
526 return EXIT_FAILURE;
527 }
528
529 float_value = 70000.1f;
530 short_value = vpMath::saturate<short>(float_value);
531 if (short_value != SHRT_MAX) {
532 std::cerr << "Fail: vpMath::saturate<short>(70000.1f)=" << short_value << " / should be " << SHRT_MAX << std::endl;
533 return EXIT_FAILURE;
534 }
535
536 float_value = -70000.1f;
537 short_value = vpMath::saturate<short>(float_value);
538 if (short_value != SHRT_MIN) {
539 std::cerr << "Fail: vpMath::saturate<short>(-70000.1f)=" << short_value << " / should be " << SHRT_MIN << std::endl;
540 return EXIT_FAILURE;
541 }
542
543 double_value = 70000.1;
544 short_value = vpMath::saturate<short>(double_value);
545 if (short_value != SHRT_MAX) {
546 std::cerr << "Fail: vpMath::saturate<short>(70000.1)=" << short_value << " / should be " << SHRT_MAX << std::endl;
547 return EXIT_FAILURE;
548 }
549
550 double_value = -70000.1;
551 short_value = vpMath::saturate<short>(double_value);
552 if (short_value != SHRT_MIN) {
553 std::cerr << "Fail: vpMath::saturate<short>(70000.1)=" << short_value << " / should be " << SHRT_MIN << std::endl;
554 return EXIT_FAILURE;
555 }
556 std::cout << "vpMath::saturate<short>() is Ok !" << std::endl;
557
558 // Test mean, median and standard deviation against Matlab with rng(0) and
559 // rand(10,1)*10
560 std::vector<double> vectorOfDoubles(10);
561 vectorOfDoubles[0] = 8.1472;
562 vectorOfDoubles[1] = 9.0579;
563 vectorOfDoubles[2] = 1.2699;
564 vectorOfDoubles[3] = 9.1338;
565 vectorOfDoubles[4] = 6.3236;
566 vectorOfDoubles[5] = 0.9754;
567 vectorOfDoubles[6] = 2.7850;
568 vectorOfDoubles[7] = 5.4688;
569 vectorOfDoubles[8] = 9.5751;
570 vectorOfDoubles[9] = 9.6489;
571
572 double res = vpMath::getMean(vectorOfDoubles);
573 if (!vpMath::equal(res, 6.2386, 0.001)) {
574 std::cerr << "Problem with vpMath::getMean()=" << res << std::endl;
575 return EXIT_FAILURE;
576 }
577 std::cout << "vpMath::getMean() is Ok !" << std::endl;
578
579 res = vpMath::getStdev(vectorOfDoubles);
580 if (!vpMath::equal(res, 3.2810, 0.001)) {
581 std::cerr << "Problem with vpMath::getStdev()=" << res << std::endl;
582 return EXIT_FAILURE;
583 }
584
585 res = vpMath::getStdev(vectorOfDoubles, true);
586 if (!vpMath::equal(res, 3.4585, 0.001)) {
587 std::cerr << "Problem with vpMath::getStdev() with Bessel correction=" << res << std::endl;
588 return EXIT_FAILURE;
589 }
590 std::cout << "vpMath::getStdev() is Ok !" << std::endl;
591
592 res = vpMath::getMedian(vectorOfDoubles);
593 if (!vpMath::equal(res, 7.2354, 0.001)) {
594 std::cerr << "Problem with vpMath::getMedian()=" << res << std::endl;
595 return EXIT_FAILURE;
596 }
597
598 // Test median with odd number of elements
599 vectorOfDoubles.push_back(1.5761);
600 res = vpMath::getMedian(vectorOfDoubles);
601 if (!vpMath::equal(res, 6.3236, 0.001)) {
602 std::cerr << "Problem with vpMath::getMedian()=" << res << std::endl;
603 return EXIT_FAILURE;
604 }
605 std::cout << "vpMath::getMedian() is Ok !" << std::endl;
606
607 // Test clamp
608#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
609 {
610 const double lower { -10. }, upper { +10. };
611 std::vector<double> testing_values { 5., -15., 15. };
612 std::vector<double> expected_values { 5., -10., 10. };
613
614 for (size_t i = 0u; i < testing_values.size(); i++) {
615 const double clamp_val = vpMath::clamp(testing_values.at(i), lower, upper);
616 if (!vpMath::equal(clamp_val, expected_values.at(i), 0.001)) {
617 std::cerr << "Problem with vpMath::clamp()=" << clamp_val << std::endl;
618 return EXIT_FAILURE;
619 }
620 }
621 std::cout << "vpMath::clamp() is Ok !" << std::endl;
622 }
623#endif
624
625 // Test vpMath::deg() and vpMath::rad()
626 {
627 vpColVector rxyz_deg_truth(3);
628 rxyz_deg_truth[0] = 10;
629 rxyz_deg_truth[1] = 20;
630 rxyz_deg_truth[2] = -30;
631 vpColVector rxyz_rad_truth(3);
632 rxyz_rad_truth[0] = vpMath::rad(rxyz_deg_truth[0]);
633 rxyz_rad_truth[1] = vpMath::rad(rxyz_deg_truth[1]);
634 rxyz_rad_truth[2] = vpMath::rad(rxyz_deg_truth[2]);
635
636 {
637 vpRxyzVector rxyz(rxyz_rad_truth);
638 vpColVector rxyz_deg = vpMath::deg(rxyz);
639 for (unsigned int i = 0u; i < rxyz_deg_truth.size(); i++) {
640 if (!vpMath::equal(rxyz_deg[i], rxyz_deg_truth[i], 0.001)) {
641 std::cerr << "Problem with vpMath::deg(vpRotationVector) " << i << ": " << rxyz_deg[i] << std::endl;
642 return EXIT_FAILURE;
643 }
644 }
645 std::cout << "vpMath::deg(vpRxyzVector) is Ok !" << std::endl;
646 }
647 {
648 vpColVector rxyz_deg = vpMath::deg(rxyz_rad_truth);
649 for (unsigned int i = 0u; i < rxyz_deg_truth.size(); i++) {
650 if (!vpMath::equal(rxyz_deg[i], rxyz_deg_truth[i], 0.001)) {
651 std::cerr << "Problem with vpMath::deg(vpColVector) " << i << ": " << rxyz_deg[i] << std::endl;
652 return EXIT_FAILURE;
653 }
654 }
655 std::cout << "vpMath::deg(vpColVector) is Ok !" << std::endl;
656 }
657 {
658 vpColVector rxyz_rad = vpMath::rad(rxyz_deg_truth);
659 for (unsigned int i = 0u; i < rxyz_deg_truth.size(); i++) {
660 if (!vpMath::equal(rxyz_rad[i], rxyz_rad_truth[i], 0.001)) {
661 std::cerr << "Problem with vpMath::rad(vpColVector) " << i << ": " << rxyz_rad[i] << std::endl;
662 return EXIT_FAILURE;
663 }
664 }
665 std::cout << "vpMath::rad(vpColVector) is Ok !" << std::endl;
666 }
667 }
668
669 std::cout << "Test succeed" << std::endl;
670 return EXIT_SUCCESS;
671}
Implementation of column vector and the associated operations.
static bool isNaN(double value)
Definition vpMath.cpp:101
static Tp saturate(unsigned char v)
Definition vpMath.h:306
static double rad(double deg)
Definition vpMath.h:129
static double getMedian(const std::vector< double > &v)
Definition vpMath.cpp:343
static double getStdev(const std::vector< double > &v, bool useBesselCorrection=false)
Definition vpMath.cpp:374
static bool equal(double x, double y, double threshold=0.001)
Definition vpMath.h:470
static T clamp(const T &v, const T &lower, const T &upper)
Definition vpMath.h:219
static int round(double x)
Definition vpMath.h:413
static bool isFinite(double value)
Definition vpMath.cpp:198
static double getMean(const std::vector< double > &v)
Definition vpMath.cpp:323
static bool isInf(double value)
Definition vpMath.cpp:151
static double deg(double rad)
Definition vpMath.h:119
static bool isNumber(const std::string &str)
Definition vpMath.cpp:235
Implementation of a rotation vector as Euler angle minimal representation.