Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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
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  * Eric Marchand
35  *
36  *****************************************************************************/
37 
44 #include <stdlib.h>
45 #include <stdio.h>
46 
47 #include <visp3/core/vpMath.h>
48 #include <visp3/core/vpColVector.h>
49 #include <visp3/core/vpGaussRand.h>
50 
51 
52 bool test(const std::string &s, const vpColVector &v, const std::vector<double> &bench)
53 {
54  static unsigned int cpt = 0;
55  std::cout << "** Test " << ++cpt << std::endl;
56  std::cout << s << "(" << v.getRows() << "," << v.getCols() << ") = [" << v.t() << "]^T" << std::endl;
57  if(bench.size() != v.size()) {
58  std::cout << "Test fails: bad size wrt bench" << std::endl;
59  return false;
60  }
61  for (unsigned int i=0; i<v.size(); i++) {
62  if (std::fabs(v[i]-bench[i]) > std::fabs(v[i])*std::numeric_limits<double>::epsilon()) {
63  std::cout << "Test fails: bad content" << std::endl;
64  return false;
65  }
66  }
67 
68  return true;
69 }
70 
71 double computeRegularSum(const vpColVector &v) {
72  double sum = 0.0;
73 
74  for(unsigned int i = 0; i < v.getRows(); i++) {
75  sum += v[i];
76  }
77 
78  return sum;
79 }
80 
81 double computeRegularSumSquare(const vpColVector &v) {
82  double sum_square = 0.0;
83 
84  for(unsigned int i = 0; i < v.getRows(); i++) {
85  sum_square += v[i] * v[i];
86  }
87 
88  return sum_square;
89 }
90 
91 double computeRegularStdev(const vpColVector &v) {
92  double mean_value = computeRegularSum(v) / v.getRows();
93  double sum_squared_diff = 0.0;
94 
95  for(unsigned int i = 0; i < v.size(); i++) {
96  sum_squared_diff += (v[i]-mean_value) * (v[i]-mean_value);
97  }
98 
99  double divisor = (double) v.size();
100 
101  return std::sqrt(sum_squared_diff / divisor);
102 }
103 
104 int main()
105 {
106  int err = 1;
107 
108  {
109  vpColVector v;
110 
111  v.resize(4);
112  v = 3;
113  std::vector<double> bench1(4, 3);
114  if (test("v", v, bench1) == false)
115  return err;
116  std::vector<double> bench2(4, 3./6);
117  v.normalize();
118  if (test("v", v, bench2) == false)
119  return err;
120 
121  v.resize(5, 1, true);
122  std::vector<double> bench3(5, 0);
123  if (test("v", v, bench3) == false)
124  return err;
125  }
126 
127  {
128  vpColVector v(4);
129  std::vector<double> bench1(4);
130  for(unsigned int i=0; i<v.size(); i++) {
131  v[i] = (double)i;
132  bench1[i] = (double)i;
133  }
134  if (test("v", v, bench1) == false)
135  return err;
136 
137  vpColVector w;
138  w.init(v, 0, 2);
139  std::vector<double> bench2;
140  bench2.push_back(0);
141  bench2.push_back(1);
142  if (test("w", w, bench2) == false)
143  return err;
144 
145  std::vector<double> bench3;
146  bench3.push_back(1);
147  bench3.push_back(2);
148  bench3.push_back(3);
149 
150  vpColVector r1;
151  for(size_t i=0; i<4; i++)
152  r1.stack((double)i);
153 
154  vpColVector r2 = r1.extract(1, 3);
155  if (test("r2", r2, bench3) == false)
156  return err;
157  }
158 
159  {
160  vpMatrix M(4, 1);
161  std::vector<double> bench(4);
162  for(unsigned int i=0; i<M.getRows(); i++) {
163  M[i][0] = i;
164  bench[i] = i;
165  }
166  if (test("M", M, bench) == false)
167  return err;
168  vpColVector v;
169  v = M;
170  if (test("v", v, bench) == false)
171  return err;
172  vpColVector w(M);
173  if (test("w", w, bench) == false)
174  return err;
175  vpColVector z1(bench);
176  if (test("z1", z1, bench) == false)
177  return err;
178  vpColVector z2 = bench;
179  if (test("z2", z2, bench) == false)
180  return err;
181  }
182 
183  {
184  vpColVector v(3);
185  v[0] = 1;
186  v[1] = 2;
187  v[2] = 3;
188  std::vector<double> bench1;
189  bench1.push_back(3);
190  bench1.push_back(6);
191  bench1.push_back(9);
192 
193  vpColVector w = v * 3;
194  // v is unchanged
195  // w is now equal to : [3 6 9]
196  if (test("w", w, bench1) == false)
197  return err;
198 
199  vpColVector x(w);
200  if (test("x", x, bench1) == false)
201  return err;
202 
203  std::vector<float> bench2;
204  bench2.push_back(3);
205  bench2.push_back(6);
206  bench2.push_back(9);
207  vpColVector y1(bench2);
208  if (test("y1", y1, bench1) == false)
209  return err;
210  vpColVector y2 = bench2;
211  if (test("y2", y2, bench1) == false)
212  return err;
213  }
214 
215  {
216  vpColVector r1(3, 1);
217  vpColVector r2 = -r1;
218  std::vector<double> bench(3,-1);
219  // v contains [-1 -1 -1]
220  if (test("r2", r2, bench) == false)
221  return err;
222  r2.stack(-2);
223  bench.push_back(-2);
224  if (test("r2", r2, bench) == false)
225  return err;
226  vpColVector r3 = vpColVector::stack(r1, r2);
227  std::vector<double> bench3(7, 1);
228  bench3[3] = bench3[4] = bench3[5] = -1;
229  bench3[6] = -2;
230  if (test("r3", r3, bench3) == false)
231  return err;
232 
233  r1.stack(r2);
234  if (test("r1", r1, bench3) == false)
235  return err;
236  }
237 
238  {
239  vpColVector r1(3, 2);
240  vpColVector r2(3, 4);
241  std::cout << "test r1: " << r1 << std::endl;
242  std::cout << "test r2: " << r2 << std::endl;
243  vpColVector r = r1 + r2;
244  std::cout << "test r1+r2: " << r1+r2 << std::endl;
245  std::cout << "test r: " << r << std::endl;
246  std::vector<double> bench(3, 6);
247  if (test("r", r, bench) == false)
248  return err;
249  r1 += r2;
250  if (test("r1", r1, bench) == false)
251  return err;
252  }
253 
254  {
255  vpColVector r1(3, 2);
256  vpColVector r2(3, 4);
257  vpColVector r = r1 - r2;
258  std::vector<double> bench(3, -2);
259  if (test("r", r, bench) == false)
260  return err;
261  r1 -= r2;
262  if (test("r1", r1, bench) == false)
263  return err;
264  }
265 
266  {
267  vpColVector r(5, 1);
268  r.clear();
269  r.resize(5);
270  r = 5;
271  std::vector<double> bench(5, 5);
272  if (test("r", r, bench) == false)
273  return err;
274  }
275 
276  {
277  // Test mean, median and standard deviation against Matlab with rng(0) and rand(10,1)*10
278  vpColVector r(10);
279  r[0] = 8.1472;
280  r[1] = 9.0579;
281  r[2] = 1.2699;
282  r[3] = 9.1338;
283  r[4] = 6.3236;
284  r[5] = 0.9754;
285  r[6] = 2.7850;
286  r[7] = 5.4688;
287  r[8] = 9.5751;
288  r[9] = 9.6489;
289 
290  std::cout << "** Test mean" << std::endl;
291  double res = vpColVector::mean(r);
292  if(!vpMath::equal(res, 6.2386, 0.001)) {
293  std::cout << "Test fails: bad mean " << res << std::endl;
294  return err;
295  }
296 
297  std::cout << "** Test stdev" << std::endl;
298  res = vpColVector::stdev(r);
299  if(!vpMath::equal(res, 3.2810, 0.001)) {
300  std::cout << "Test fails: bad stdev " << res << std::endl;
301  return err;
302  }
303 
304  std::cout << "** Test stdev(bessel)" << std::endl;
305  res = vpColVector::stdev(r, true);
306  if(!vpMath::equal(res, 3.4585, 0.001)) {
307  std::cout << "Test fails: bad stdev(bessel) " << res << std::endl;
308  return err;
309  }
310 
311  std::cout << "** Test median" << std::endl;
312  res = vpColVector::median(r);
313  if(!vpMath::equal(res, 7.2354, 0.001)) {
314  std::cout << "Test fails: bad median " << res << std::endl;
315  return err;
316  }
317 
318  // Test median with odd number of elements
319  std::cout << "** Test median (odd)" << std::endl;
320  r.stack(1.5761);
321  res = vpColVector::median(r);
322  if(!vpMath::equal(res, 6.3236, 0.001)) {
323  std::cout << "Test fails: bad median (odd) " << res << std::endl;
324  return err;
325  }
326  std::cout << "r: [" << r << "]^T" << std::endl;
327  r.print(std::cout, 8, "r");
328  }
329 
330  //Test sum, sumSquare, stdev
331  {
332  srand(0);
333  vpGaussRand noise(10.0, 0.0);
334 
335  int nbIterations = 1000;
336  unsigned int size = 117;
337 
338  vpColVector v(size);
339  for(unsigned int cpt = 0; cpt < v.getRows(); cpt++) {
340  v[cpt] = rand() % 1000 + noise();
341  }
342 
343  std::cout << "\nv.getRows()=" << v.getRows() << std::endl;
344 
345  double regular_sum = 0.0;
346  double t_regular = vpTime::measureTimeMs();
347  for(int iteration = 0; iteration < nbIterations; iteration++) {
348  regular_sum += computeRegularSum(v);
349  }
350  t_regular = vpTime::measureTimeMs() - t_regular;
351 
352  double sse_sum = 0.0;
353  double t_sse = vpTime::measureTimeMs();
354  for(int iteration = 0; iteration < nbIterations; iteration++) {
355  sse_sum += v.sum();
356  }
357  t_sse = vpTime::measureTimeMs() - t_sse;
358 
359  std::cout << "\nregular_sum=" << regular_sum << " ; sse_sum=" << sse_sum << std::endl;
360  std::cout << "t_regular=" << t_regular << " ms ; t_sse=" << t_sse << " ms" << std::endl;
361  std::cout << "Speed-up: " << (t_regular/t_sse) << "X" << std::endl;
362 
363  if( !vpMath::equal(regular_sum, sse_sum, std::numeric_limits<double>::epsilon()) ) {
364  std::cerr << "Problem when computing v.sum()!" << std::endl;
365  return -1;
366  }
367 
368 
369  double regular_sumSquare = 0.0;
370  t_regular = vpTime::measureTimeMs();
371  for(int iteration = 0; iteration < nbIterations; iteration++) {
372  regular_sumSquare += computeRegularSumSquare(v);
373  }
374  t_regular = vpTime::measureTimeMs() - t_regular;
375 
376  double sse_sumSquare = 0.0;
377  t_sse = vpTime::measureTimeMs();
378  for(int iteration = 0; iteration < nbIterations; iteration++) {
379  sse_sumSquare += v.sumSquare();
380  }
381  t_sse = vpTime::measureTimeMs() - t_sse;
382 
383  std::cout << "\nregular_sumSquare=" << regular_sumSquare << " ; sse_sumSquare=" << sse_sumSquare << std::endl;
384  std::cout << "t_regular=" << t_regular << " ms ; t_sse=" << t_sse << " ms" << std::endl;
385  std::cout << "Speed-up: " << (t_regular/t_sse) << "X" << std::endl;
386 
387  if( !vpMath::equal(regular_sumSquare, sse_sumSquare, std::numeric_limits<double>::epsilon()) ) {
388  std::cerr << "Problem when computing v.sumSquare()!" << std::endl;
389  return -1;
390  }
391 
392 
393  double regular_stdev = 0.0;
394  t_regular = vpTime::measureTimeMs();
395  for(int iteration = 0; iteration < nbIterations; iteration++) {
396  regular_stdev += computeRegularStdev(v);
397  }
398  t_regular = vpTime::measureTimeMs() - t_regular;
399 
400  double sse_stdev = 0.0;
401  t_sse = vpTime::measureTimeMs();
402  for(int iteration = 0; iteration < nbIterations; iteration++) {
403  sse_stdev += vpColVector::stdev(v, false);
404  }
405  t_sse = vpTime::measureTimeMs() - t_sse;
406 
407  std::cout << "\nregular_stdev=" << regular_stdev << " ; sse_stdev=" << sse_stdev << std::endl;
408  std::cout << "t_regular=" << t_regular << " ms ; t_sse=" << t_sse << " ms" << std::endl;
409  std::cout << "Speed-up: " << (t_regular/t_sse) << "X" << std::endl;
410 
411  if( !vpMath::equal(regular_stdev, sse_stdev, std::numeric_limits<double>::epsilon()) ) {
412  std::cerr << "Problem when computing vpColVector::stdev()!" << std::endl;
413  return -1;
414  }
415  }
416 
417  std::cout << "\nAll tests succeed" << std::endl;
418  return 0;
419 }
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:97
vpColVector extract(unsigned int r, unsigned int colsize) const
Definition: vpColVector.h:149
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:306
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:156
unsigned int getCols() const
Return the number of columns of the 2D array.
Definition: vpArray2D.h:154
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:93
static double median(const vpColVector &v)
int print(std::ostream &s, unsigned int length, char const *intro=0) const
vpColVector & normalize()
void clear()
Definition: vpColVector.h:106
vpRowVector t() const
static double mean(const vpColVector &v)
unsigned int getRows() const
Return the number of rows of the 2D array.
Definition: vpArray2D.h:152
double sumSquare() const
Class for generating random number with normal probability density.
Definition: vpGaussRand.h:119
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
void init(const vpColVector &v, unsigned int r, unsigned int nrows)
double sum() const
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:225