Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
testColVector.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 vpColVector functionalities.
32  */
33 
40 #include <stdio.h>
41 #include <stdlib.h>
42 
43 #include <visp3/core/vpColVector.h>
44 #include <visp3/core/vpGaussRand.h>
45 #include <visp3/core/vpMath.h>
46 
47 #ifdef ENABLE_VISP_NAMESPACE
48 using namespace VISP_NAMESPACE_NAME;
49 #endif
50 
51 namespace
52 {
53 bool test(const std::string &s, const vpColVector &v, const std::vector<double> &bench)
54 {
55  static unsigned int cpt = 0;
56  std::cout << "** Test " << ++cpt << std::endl;
57  std::cout << s << "(" << v.getRows() << "," << v.getCols() << ") = [" << v.t() << "]^T" << std::endl;
58  if (bench.size() != v.size()) {
59  std::cout << "Test fails: bad size wrt bench" << std::endl;
60  return false;
61  }
62  for (unsigned int i = 0; i < v.size(); i++) {
63  if (std::fabs(v[i] - bench[i]) > std::fabs(v[i]) * std::numeric_limits<double>::epsilon()) {
64  std::cout << "Test fails: bad content" << std::endl;
65  return false;
66  }
67  }
68 
69  return true;
70 }
71 
72 double getRandomValues(double min, double max) { return (max - min) * ((double)rand() / (double)RAND_MAX) + min; }
73 } // namespace
74 
75 int main()
76 {
77  {
78  vpColVector v1(7, 0.1), v2;
79  if (v1 == v2) {
80  std::cerr << "Issue with vpColVector comparison operator." << std::endl;
81  return EXIT_FAILURE;
82  }
83  v2 = v1;
84  if (v1 != v2) {
85  std::cerr << "Issue with vpColVector comparison operator." << std::endl;
86  return EXIT_FAILURE;
87  }
88  v2[3] = 0.2;
89  if (v1 == v2) {
90  std::cerr << "Issue with vpColVector comparison operator." << std::endl;
91  return EXIT_FAILURE;
92  }
93  }
94  {
95  vpColVector v;
96 
97  v.resize(4);
98  v = 3;
99  std::vector<double> bench1(4, 3);
100  if (test("v", v, bench1) == false)
101  return EXIT_FAILURE;
102  std::vector<double> bench2(4, 3. / 6);
103  v.normalize();
104  if (test("v", v, bench2) == false)
105  return EXIT_FAILURE;
106 
107  v.resize(5, 1, true);
108  std::vector<double> bench3(5, 0);
109  if (test("v", v, bench3) == false)
110  return EXIT_FAILURE;
111  }
112 
113  {
114  vpColVector v(4);
115  std::vector<double> bench1(4);
116  for (unsigned int i = 0; i < v.size(); i++) {
117  v[i] = (double)i;
118  bench1[i] = (double)i;
119  }
120  if (test("v", v, bench1) == false)
121  return EXIT_FAILURE;
122 
123  vpColVector w;
124  w.init(v, 0, 2);
125  std::vector<double> bench2;
126  bench2.push_back(0);
127  bench2.push_back(1);
128  if (test("w", w, bench2) == false)
129  return EXIT_FAILURE;
130 
131  std::vector<double> bench3;
132  bench3.push_back(1);
133  bench3.push_back(2);
134  bench3.push_back(3);
135 
136  vpColVector r1;
137  for (size_t i = 0; i < 4; i++)
138  r1.stack((double)i);
139 
140  vpColVector r2 = r1.extract(1, 3);
141  if (test("r2", r2, bench3) == false)
142  return EXIT_FAILURE;
143  }
144 
145  {
146  vpMatrix M(4, 1);
147  std::vector<double> bench(4);
148  for (unsigned int i = 0; i < M.getRows(); i++) {
149  M[i][0] = i;
150  bench[i] = i;
151  }
152  if (test("M", vpColVector(M), bench) == false)
153  return EXIT_FAILURE;
154  vpColVector v;
155  v = M;
156  if (test("v", v, bench) == false)
157  return EXIT_FAILURE;
158  vpColVector w(M);
159  if (test("w", w, bench) == false)
160  return EXIT_FAILURE;
161  vpColVector z1(bench);
162  if (test("z1", z1, bench) == false)
163  return EXIT_FAILURE;
164  vpColVector z2 = vpColVector(bench);
165  if (test("z2", z2, bench) == false)
166  return EXIT_FAILURE;
167  }
168 
169  {
170  vpColVector v(3);
171  v[0] = 1;
172  v[1] = 2;
173  v[2] = 3;
174  std::vector<double> bench1;
175  bench1.push_back(3);
176  bench1.push_back(6);
177  bench1.push_back(9);
178 
179  vpColVector w = v * 3;
180  // v is unchanged
181  // w is now equal to : [3 6 9]
182  if (test("w", w, bench1) == false)
183  return EXIT_FAILURE;
184 
185  vpColVector x(w);
186  if (test("x", x, bench1) == false)
187  return EXIT_FAILURE;
188 
189  std::vector<float> bench2;
190  bench2.push_back(3);
191  bench2.push_back(6);
192  bench2.push_back(9);
193  vpColVector y1(bench2);
194  if (test("y1", y1, bench1) == false)
195  return EXIT_FAILURE;
196  vpColVector y2 = vpColVector(bench2);
197  if (test("y2", y2, bench1) == false)
198  return EXIT_FAILURE;
199  }
200 
201  {
202  vpColVector r1(3, 1);
203  vpColVector r2 = -r1;
204  std::vector<double> bench(3, -1);
205  // v contains [-1 -1 -1]
206  if (test("r2", r2, bench) == false)
207  return EXIT_FAILURE;
208  r2.stack(-2);
209  bench.push_back(-2);
210  if (test("r2", r2, bench) == false)
211  return EXIT_FAILURE;
212  vpColVector r3 = vpColVector::stack(r1, r2);
213  std::vector<double> bench3(7, 1);
214  bench3[3] = bench3[4] = bench3[5] = -1;
215  bench3[6] = -2;
216  if (test("r3", r3, bench3) == false)
217  return EXIT_FAILURE;
218 
219  r1.stack(r2);
220  if (test("r1", r1, bench3) == false)
221  return EXIT_FAILURE;
222  }
223 
224  {
225  vpColVector r1(3, 2);
226  vpColVector r2(3, 4);
227  std::cout << "test r1: " << r1 << std::endl;
228  std::cout << "test r2: " << r2 << std::endl;
229  vpColVector r = r1 + r2;
230  std::cout << "test r1+r2: " << r1 + r2 << std::endl;
231  std::cout << "test r: " << r << std::endl;
232  std::vector<double> bench(3, 6);
233  if (test("r", r, bench) == false)
234  return EXIT_FAILURE;
235  r1 += r2;
236  if (test("r1", r1, bench) == false)
237  return EXIT_FAILURE;
238  }
239 
240  {
241  vpColVector r1(3, 2);
242  vpColVector r2(3, 4);
243  vpColVector r = r1 - r2;
244  std::vector<double> bench(3, -2);
245  if (test("r", r, bench) == false)
246  return EXIT_FAILURE;
247  r1 -= r2;
248  if (test("r1", r1, bench) == false)
249  return EXIT_FAILURE;
250  }
251 
252  {
253  vpColVector r(5, 1);
254  r.clear();
255  r.resize(5);
256  r = 5;
257  std::vector<double> bench(5, 5);
258  if (test("r", r, bench) == false)
259  return EXIT_FAILURE;
260  }
261 
262  {
263  // Test mean, median and standard deviation against Matlab with rng(0) and
264  // rand(10,1)*10
265  vpColVector r(10);
266  r[0] = 8.1472;
267  r[1] = 9.0579;
268  r[2] = 1.2699;
269  r[3] = 9.1338;
270  r[4] = 6.3236;
271  r[5] = 0.9754;
272  r[6] = 2.7850;
273  r[7] = 5.4688;
274  r[8] = 9.5751;
275  r[9] = 9.6489;
276 
277  std::cout << "** Test mean" << std::endl;
278  double res = vpColVector::mean(r);
279  if (!vpMath::equal(res, 6.2386, 0.001)) {
280  std::cout << "Test fails: bad mean " << res << std::endl;
281  return EXIT_FAILURE;
282  }
283 
284  std::cout << "** Test stdev" << std::endl;
285  res = vpColVector::stdev(r);
286  if (!vpMath::equal(res, 3.2810, 0.001)) {
287  std::cout << "Test fails: bad stdev " << res << std::endl;
288  return EXIT_FAILURE;
289  }
290 
291  std::cout << "** Test stdev(bessel)" << std::endl;
292  res = vpColVector::stdev(r, true);
293  if (!vpMath::equal(res, 3.4585, 0.001)) {
294  std::cout << "Test fails: bad stdev(bessel) " << res << std::endl;
295  return EXIT_FAILURE;
296  }
297 
298  std::cout << "** Test median" << std::endl;
299  res = vpColVector::median(r);
300  if (!vpMath::equal(res, 7.2354, 0.001)) {
301  std::cout << "Test fails: bad median " << res << std::endl;
302  return EXIT_FAILURE;
303  }
304 
305  // Test median with odd number of elements
306  std::cout << "** Test median (odd)" << std::endl;
307  r.stack(1.5761);
308  res = vpColVector::median(r);
309  if (!vpMath::equal(res, 6.3236, 0.001)) {
310  std::cout << "Test fails: bad median (odd) " << res << std::endl;
311  return EXIT_FAILURE;
312  }
313  std::cout << "r: [" << r << "]^T" << std::endl;
314  r.print(std::cout, 8, "r");
315  }
316 
317  {
318  // Test insert with big vector
319  unsigned int nb = 1000;
320  const unsigned int size = 10000;
321  std::vector<vpColVector> vec(nb);
322 
323  for (size_t i = 0; i < nb; i++) {
324  vpColVector v(size);
325  for (unsigned int j = 0; j < size; j++) {
326  v[j] = getRandomValues(-100.0, 100.0);
327  }
328  vec[i] = v;
329  }
330 
331  vpColVector v_big(nb * size);
332  double t = vpTime::measureTimeMs();
333  for (unsigned int i = 0; i < nb; i++) {
334  v_big.insert(i * size, vec[(size_t)i]);
335  }
336  t = vpTime::measureTimeMs() - t;
337  std::cout << "\nBig insert: " << t << " ms" << std::endl;
338 
339  for (unsigned int i = 0; i < nb; i++) {
340  for (unsigned int j = 0; j < size; j++) {
341  if (!vpMath::equal(v_big[i * size + j], vec[(size_t)i][j], std::numeric_limits<double>::epsilon())) {
342  std::cerr << "Problem in vpColVector insert()!" << std::endl;
343  return EXIT_FAILURE;
344  }
345  }
346  }
347 
348  // Try to insert empty vpColVector
349  vpColVector v1(2), v2, v3;
350  v1.insert(0, v2);
351  v3.insert(0, v2);
352 
353  std::cout << "Insert empty vectors:" << std::endl;
354  std::cout << "v1: " << v1.t() << std::endl;
355  std::cout << "v2: " << v2.t() << std::endl;
356  std::cout << "v3: " << v3.t() << std::endl;
357  }
358 
359  {
360  std::cout << "** Test conversion to/from std::vector" << std::endl;
361  std::vector<double> std_vector(5);
362  for (size_t i = 0; i < std_vector.size(); i++) {
363  std_vector[i] = (double)i;
364  }
365  vpColVector v(std_vector);
366  if (test("v", v, std_vector) == false)
367  return EXIT_FAILURE;
368 
369  std_vector.clear();
370  std_vector = v.toStdVector();
371  if (test("v", v, std_vector) == false)
372  return EXIT_FAILURE;
373  }
374 
375  {
376  std::cout << "** Test operator == and operator !=" << std::endl;
377  vpColVector v(3, 1.);
378  double val = 1.;
379  std::cout << "v: " << v.t() << " != " << val << std::endl;
380  if (v != val)
381  return EXIT_FAILURE;
382  val = 0.;
383  std::cout << "v: " << v.t() << " == " << val << std::endl;
384  if (v == val)
385  return EXIT_FAILURE;
386  v[1] = val;
387  std::cout << "v: " << v.t() << " == " << val << std::endl;
388  if (v == val)
389  return EXIT_FAILURE;
390  }
391  std::cout << "\nAll tests succeed" << std::endl;
392  return EXIT_SUCCESS;
393 }
unsigned int getCols() const
Definition: vpArray2D.h:337
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:349
unsigned int getRows() const
Definition: vpArray2D.h:347
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
vpColVector extract(unsigned int r, unsigned int colsize) const
Definition: vpColVector.h:405
vpColVector & normalize()
static double median(const vpColVector &v)
int print(std::ostream &s, unsigned int length, char const *intro=0) const
void init(const vpColVector &v, unsigned int r, unsigned int nrows)
void stack(double d)
std::vector< double > toStdVector() const
static double mean(const vpColVector &v)
vpRowVector t() const
void clear()
Definition: vpColVector.h:290
static double stdev(const vpColVector &v, bool useBesselCorrection=false)
void insert(unsigned int i, const vpColVector &v)
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1143
static bool equal(double x, double y, double threshold=0.001)
Definition: vpMath.h:458
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
VISP_EXPORT double measureTimeMs()