Visual Servoing Platform  version 3.1.0
testColVector.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 modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Test some vpColVector functionalities.
33  *
34  * Authors:
35  * Eric Marchand
36  *
37  *****************************************************************************/
38 
45 #include <stdio.h>
46 #include <stdlib.h>
47 
48 #include <visp3/core/vpColVector.h>
49 #include <visp3/core/vpGaussRand.h>
50 #include <visp3/core/vpMath.h>
51 
52 namespace
53 {
54 bool test(const std::string &s, const vpColVector &v, const std::vector<double> &bench)
55 {
56  static unsigned int cpt = 0;
57  std::cout << "** Test " << ++cpt << std::endl;
58  std::cout << s << "(" << v.getRows() << "," << v.getCols() << ") = [" << v.t() << "]^T" << std::endl;
59  if (bench.size() != v.size()) {
60  std::cout << "Test fails: bad size wrt bench" << std::endl;
61  return false;
62  }
63  for (unsigned int i = 0; i < v.size(); i++) {
64  if (std::fabs(v[i] - bench[i]) > std::fabs(v[i]) * std::numeric_limits<double>::epsilon()) {
65  std::cout << "Test fails: bad content" << std::endl;
66  return false;
67  }
68  }
69 
70  return true;
71 }
72 
73 double computeRegularSum(const vpColVector &v)
74 {
75  double sum = 0.0;
76 
77  for (unsigned int i = 0; i < v.getRows(); i++) {
78  sum += v[i];
79  }
80 
81  return sum;
82 }
83 
84 double computeRegularSumSquare(const vpColVector &v)
85 {
86  double sum_square = 0.0;
87 
88  for (unsigned int i = 0; i < v.getRows(); i++) {
89  sum_square += v[i] * v[i];
90  }
91 
92  return sum_square;
93 }
94 
95 double computeRegularStdev(const vpColVector &v)
96 {
97  double mean_value = computeRegularSum(v) / v.getRows();
98  double sum_squared_diff = 0.0;
99 
100  for (unsigned int i = 0; i < v.size(); i++) {
101  sum_squared_diff += (v[i] - mean_value) * (v[i] - mean_value);
102  }
103 
104  double divisor = (double)v.size();
105 
106  return std::sqrt(sum_squared_diff / divisor);
107 }
108 
109 double getRandomValues(const double min, const double max)
110 {
111  return (max - min) * ((double)rand() / (double)RAND_MAX) + min;
112 }
113 }
114 
115 int main()
116 {
117  int err = 1;
118 
119  {
120  vpColVector v;
121 
122  v.resize(4);
123  v = 3;
124  std::vector<double> bench1(4, 3);
125  if (test("v", v, bench1) == false)
126  return err;
127  std::vector<double> bench2(4, 3. / 6);
128  v.normalize();
129  if (test("v", v, bench2) == false)
130  return err;
131 
132  v.resize(5, 1, true);
133  std::vector<double> bench3(5, 0);
134  if (test("v", v, bench3) == false)
135  return err;
136  }
137 
138  {
139  vpColVector v(4);
140  std::vector<double> bench1(4);
141  for (unsigned int i = 0; i < v.size(); i++) {
142  v[i] = (double)i;
143  bench1[i] = (double)i;
144  }
145  if (test("v", v, bench1) == false)
146  return err;
147 
148  vpColVector w;
149  w.init(v, 0, 2);
150  std::vector<double> bench2;
151  bench2.push_back(0);
152  bench2.push_back(1);
153  if (test("w", w, bench2) == false)
154  return err;
155 
156  std::vector<double> bench3;
157  bench3.push_back(1);
158  bench3.push_back(2);
159  bench3.push_back(3);
160 
161  vpColVector r1;
162  for (size_t i = 0; i < 4; i++)
163  r1.stack((double)i);
164 
165  vpColVector r2 = r1.extract(1, 3);
166  if (test("r2", r2, bench3) == false)
167  return err;
168  }
169 
170  {
171  vpMatrix M(4, 1);
172  std::vector<double> bench(4);
173  for (unsigned int i = 0; i < M.getRows(); i++) {
174  M[i][0] = i;
175  bench[i] = i;
176  }
177  if (test("M", M, bench) == false)
178  return err;
179  vpColVector v;
180  v = M;
181  if (test("v", v, bench) == false)
182  return err;
183  vpColVector w(M);
184  if (test("w", w, bench) == false)
185  return err;
186  vpColVector z1(bench);
187  if (test("z1", z1, bench) == false)
188  return err;
189  vpColVector z2 = bench;
190  if (test("z2", z2, bench) == false)
191  return err;
192  }
193 
194  {
195  vpColVector v(3);
196  v[0] = 1;
197  v[1] = 2;
198  v[2] = 3;
199  std::vector<double> bench1;
200  bench1.push_back(3);
201  bench1.push_back(6);
202  bench1.push_back(9);
203 
204  vpColVector w = v * 3;
205  // v is unchanged
206  // w is now equal to : [3 6 9]
207  if (test("w", w, bench1) == false)
208  return err;
209 
210  vpColVector x(w);
211  if (test("x", x, bench1) == false)
212  return err;
213 
214  std::vector<float> bench2;
215  bench2.push_back(3);
216  bench2.push_back(6);
217  bench2.push_back(9);
218  vpColVector y1(bench2);
219  if (test("y1", y1, bench1) == false)
220  return err;
221  vpColVector y2 = bench2;
222  if (test("y2", y2, bench1) == false)
223  return err;
224  }
225 
226  {
227  vpColVector r1(3, 1);
228  vpColVector r2 = -r1;
229  std::vector<double> bench(3, -1);
230  // v contains [-1 -1 -1]
231  if (test("r2", r2, bench) == false)
232  return err;
233  r2.stack(-2);
234  bench.push_back(-2);
235  if (test("r2", r2, bench) == false)
236  return err;
237  vpColVector r3 = vpColVector::stack(r1, r2);
238  std::vector<double> bench3(7, 1);
239  bench3[3] = bench3[4] = bench3[5] = -1;
240  bench3[6] = -2;
241  if (test("r3", r3, bench3) == false)
242  return err;
243 
244  r1.stack(r2);
245  if (test("r1", r1, bench3) == false)
246  return err;
247  }
248 
249  {
250  vpColVector r1(3, 2);
251  vpColVector r2(3, 4);
252  std::cout << "test r1: " << r1 << std::endl;
253  std::cout << "test r2: " << r2 << std::endl;
254  vpColVector r = r1 + r2;
255  std::cout << "test r1+r2: " << r1 + r2 << std::endl;
256  std::cout << "test r: " << r << std::endl;
257  std::vector<double> bench(3, 6);
258  if (test("r", r, bench) == false)
259  return err;
260  r1 += r2;
261  if (test("r1", r1, bench) == false)
262  return err;
263  }
264 
265  {
266  vpColVector r1(3, 2);
267  vpColVector r2(3, 4);
268  vpColVector r = r1 - r2;
269  std::vector<double> bench(3, -2);
270  if (test("r", r, bench) == false)
271  return err;
272  r1 -= r2;
273  if (test("r1", r1, bench) == false)
274  return err;
275  }
276 
277  {
278  vpColVector r(5, 1);
279  r.clear();
280  r.resize(5);
281  r = 5;
282  std::vector<double> bench(5, 5);
283  if (test("r", r, bench) == false)
284  return err;
285  }
286 
287  {
288  // Test mean, median and standard deviation against Matlab with rng(0) and
289  // rand(10,1)*10
290  vpColVector r(10);
291  r[0] = 8.1472;
292  r[1] = 9.0579;
293  r[2] = 1.2699;
294  r[3] = 9.1338;
295  r[4] = 6.3236;
296  r[5] = 0.9754;
297  r[6] = 2.7850;
298  r[7] = 5.4688;
299  r[8] = 9.5751;
300  r[9] = 9.6489;
301 
302  std::cout << "** Test mean" << std::endl;
303  double res = vpColVector::mean(r);
304  if (!vpMath::equal(res, 6.2386, 0.001)) {
305  std::cout << "Test fails: bad mean " << res << std::endl;
306  return err;
307  }
308 
309  std::cout << "** Test stdev" << std::endl;
310  res = vpColVector::stdev(r);
311  if (!vpMath::equal(res, 3.2810, 0.001)) {
312  std::cout << "Test fails: bad stdev " << res << std::endl;
313  return err;
314  }
315 
316  std::cout << "** Test stdev(bessel)" << std::endl;
317  res = vpColVector::stdev(r, true);
318  if (!vpMath::equal(res, 3.4585, 0.001)) {
319  std::cout << "Test fails: bad stdev(bessel) " << res << std::endl;
320  return err;
321  }
322 
323  std::cout << "** Test median" << std::endl;
324  res = vpColVector::median(r);
325  if (!vpMath::equal(res, 7.2354, 0.001)) {
326  std::cout << "Test fails: bad median " << res << std::endl;
327  return err;
328  }
329 
330  // Test median with odd number of elements
331  std::cout << "** Test median (odd)" << std::endl;
332  r.stack(1.5761);
333  res = vpColVector::median(r);
334  if (!vpMath::equal(res, 6.3236, 0.001)) {
335  std::cout << "Test fails: bad median (odd) " << res << std::endl;
336  return err;
337  }
338  std::cout << "r: [" << r << "]^T" << std::endl;
339  r.print(std::cout, 8, "r");
340  }
341 
342  // Test sum, sumSquare, stdev
343  {
344  srand(0);
345  vpGaussRand noise(10.0, 0.0);
346 
347  int nbIterations = 1000;
348  unsigned int size = 117;
349 
350  vpColVector v(size);
351  for (unsigned int cpt = 0; cpt < v.getRows(); cpt++) {
352  v[cpt] = rand() % 1000 + noise();
353  }
354 
355  std::cout << "\nv.getRows()=" << v.getRows() << std::endl;
356 
357  double regular_sum = 0.0;
358  double t_regular = vpTime::measureTimeMs();
359  for (int iteration = 0; iteration < nbIterations; iteration++) {
360  regular_sum += computeRegularSum(v);
361  }
362  t_regular = vpTime::measureTimeMs() - t_regular;
363 
364  double sse_sum = 0.0;
365  double t_sse = vpTime::measureTimeMs();
366  for (int iteration = 0; iteration < nbIterations; iteration++) {
367  sse_sum += v.sum();
368  }
369  t_sse = vpTime::measureTimeMs() - t_sse;
370 
371  std::cout << "\nregular_sum=" << regular_sum << " ; sse_sum=" << sse_sum << std::endl;
372  std::cout << "t_regular=" << t_regular << " ms ; t_sse=" << t_sse << " ms" << std::endl;
373  std::cout << "Speed-up: " << (t_regular / t_sse) << "X" << std::endl;
374 
375  if (!vpMath::equal(regular_sum, sse_sum, std::numeric_limits<double>::epsilon())) {
376  std::cerr << "Problem when computing v.sum()!" << std::endl;
377  return EXIT_FAILURE;
378  }
379 
380  double regular_sumSquare = 0.0;
381  t_regular = vpTime::measureTimeMs();
382  for (int iteration = 0; iteration < nbIterations; iteration++) {
383  regular_sumSquare += computeRegularSumSquare(v);
384  }
385  t_regular = vpTime::measureTimeMs() - t_regular;
386 
387  double sse_sumSquare = 0.0;
388  t_sse = vpTime::measureTimeMs();
389  for (int iteration = 0; iteration < nbIterations; iteration++) {
390  sse_sumSquare += v.sumSquare();
391  }
392  t_sse = vpTime::measureTimeMs() - t_sse;
393 
394  std::cout << "\nregular_sumSquare=" << regular_sumSquare << " ; sse_sumSquare=" << sse_sumSquare << std::endl;
395  std::cout << "t_regular=" << t_regular << " ms ; t_sse=" << t_sse << " ms" << std::endl;
396  std::cout << "Speed-up: " << (t_regular / t_sse) << "X" << std::endl;
397 
398  if (!vpMath::equal(regular_sumSquare, sse_sumSquare, std::numeric_limits<double>::epsilon())) {
399  std::cerr << "Problem when computing v.sumSquare()!" << std::endl;
400  return EXIT_FAILURE;
401  }
402 
403  double regular_stdev = 0.0;
404  t_regular = vpTime::measureTimeMs();
405  for (int iteration = 0; iteration < nbIterations; iteration++) {
406  regular_stdev += computeRegularStdev(v);
407  }
408  t_regular = vpTime::measureTimeMs() - t_regular;
409 
410  double sse_stdev = 0.0;
411  t_sse = vpTime::measureTimeMs();
412  for (int iteration = 0; iteration < nbIterations; iteration++) {
413  sse_stdev += vpColVector::stdev(v, false);
414  }
415  t_sse = vpTime::measureTimeMs() - t_sse;
416 
417  std::cout << "\nregular_stdev=" << regular_stdev << " ; sse_stdev=" << sse_stdev << std::endl;
418  std::cout << "t_regular=" << t_regular << " ms ; t_sse=" << t_sse << " ms" << std::endl;
419  std::cout << "Speed-up: " << (t_regular / t_sse) << "X" << std::endl;
420 
421  if (!vpMath::equal(regular_stdev, sse_stdev, std::numeric_limits<double>::epsilon())) {
422  std::cerr << "Problem when computing vpColVector::stdev()!" << std::endl;
423  return EXIT_FAILURE;
424  }
425  }
426 
427  {
428  // Test insert with big vector
429  const unsigned int nb = 1000;
430  const unsigned int size = 10000;
431  std::vector<vpColVector> vec(nb);
432 
433  for (size_t i = 0; i < nb; i++) {
434  vpColVector v(size);
435  for (unsigned int j = 0; j < size; j++) {
436  v[j] = getRandomValues(-100.0, 100.0);
437  }
438  vec[i] = v;
439  }
440 
441  vpColVector v_big(nb * size);
442  double t = vpTime::measureTimeMs();
443  for (unsigned int i = 0; i < nb; i++) {
444  v_big.insert(i * size, vec[(size_t)i]);
445  }
446  t = vpTime::measureTimeMs() - t;
447  std::cout << "\nBig insert: " << t << " ms" << std::endl;
448 
449  for (unsigned int i = 0; i < nb; i++) {
450  for (unsigned int j = 0; j < size; j++) {
451  if (!vpMath::equal(v_big[i * size + j], vec[(size_t)i][j], std::numeric_limits<double>::epsilon())) {
452  std::cerr << "Problem in vpColVector insert()!" << std::endl;
453  return EXIT_FAILURE;
454  }
455  }
456  }
457 
458  // Try to insert empty vpColVector
459  vpColVector v1(2), v2, v3;
460  v1.insert(0, v2);
461  v3.insert(0, v2);
462 
463  std::cout << "Insert empty vectors:" << std::endl;
464  std::cout << "v1: " << v1.t() << std::endl;
465  std::cout << "v2: " << v2.t() << std::endl;
466  std::cout << "v3: " << v3.t() << std::endl;
467  }
468 
469  std::cout << "\nAll tests succeed" << std::endl;
470  return EXIT_SUCCESS;
471 }
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:104
void stack(const double &d)
static double stdev(const vpColVector &v, const bool useBesselCorrection=false)
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:290
vpColVector extract(unsigned int r, unsigned int colsize) const
Definition: vpColVector.h:158
unsigned int getRows() const
Definition: vpArray2D.h:156
vpRowVector t() const
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:158
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:88
double sum() const
static double median(const vpColVector &v)
unsigned int getCols() const
Definition: vpArray2D.h:146
vpColVector & normalize()
void clear()
Definition: vpColVector.h:113
static double mean(const vpColVector &v)
void insert(unsigned int i, const vpColVector &v)
int print(std::ostream &s, unsigned int length, char const *intro=0) const
Class for generating random number with normal probability density.
Definition: vpGaussRand.h:120
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
void init(const vpColVector &v, unsigned int r, unsigned int nrows)
double sumSquare() const
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:241