Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
testRowVector.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/vpMath.h>
44 #include <visp3/core/vpRowVector.h>
45 
46 #ifdef ENABLE_VISP_NAMESPACE
47 using namespace VISP_NAMESPACE_NAME;
48 #endif
49 
50 bool test(const std::string &s, const vpRowVector &v, const std::vector<double> &bench)
51 {
52  static unsigned int cpt = 0;
53  std::cout << "** Test " << ++cpt << std::endl;
54  std::cout << s << "(" << v.getRows() << "," << v.getCols() << ") = [" << v << "]" << std::endl;
55  if (bench.size() != v.size()) {
56  std::cout << "Test fails: bad size wrt bench" << std::endl;
57  return false;
58  }
59  for (unsigned int i = 0; i < v.size(); i++) {
60  if (std::fabs(v[i] - bench[i]) > std::fabs(v[i]) * std::numeric_limits<double>::epsilon()) {
61  std::cout << "Test fails: bad content" << std::endl;
62  return false;
63  }
64  }
65 
66  return true;
67 }
68 
69 int main()
70 {
71  int err = 1;
72 
73  {
74  vpRowVector v;
75 
76  v.resize(4);
77  v = 3;
78  std::vector<double> bench1(4, 3);
79  if (test("v", v, bench1) == false)
80  return err;
81  std::vector<double> bench2(4, 3. / 6);
82  v.normalize();
83  if (test("v", v, bench2) == false)
84  return err;
85 
86  v.resize(1, 5, true);
87  std::vector<double> bench3(5, 0);
88  if (test("v", v, bench3) == false)
89  return err;
90  }
91 
92  {
93  vpRowVector v(4);
94  std::vector<double> bench1(4);
95  for (unsigned int i = 0; i < v.size(); i++) {
96  v[i] = (double)i;
97  bench1[i] = (double)i;
98  }
99  if (test("v", v, bench1) == false)
100  return err;
101 
102  vpRowVector w;
103  w.init(v, 0, 2);
104  std::vector<double> bench2;
105  bench2.push_back(0);
106  bench2.push_back(1);
107  if (test("w", w, bench2) == false)
108  return err;
109 
110  std::vector<double> bench3;
111  bench3.push_back(1);
112  bench3.push_back(2);
113  bench3.push_back(3);
114 
115  vpRowVector r1;
116  for (size_t i = 0; i < 4; i++)
117  r1.stack((double)i);
118 
119  vpRowVector r2 = r1.extract(1, 3);
120  if (test("r2", r2, bench3) == false)
121  return err;
122  }
123  {
124  vpMatrix M(1, 4);
125  std::vector<double> bench(4);
126  for (unsigned int i = 0; i < M.getCols(); i++) {
127  M[0][i] = i;
128  bench[i] = i;
129  }
130  if (test("M", vpRowVector(M), bench) == false)
131  return err;
132  vpRowVector v;
133  v = M;
134  if (test("v", v, bench) == false)
135  return err;
136  vpRowVector w(M);
137  if (test("w", w, bench) == false)
138  return err;
139  vpRowVector z1(bench);
140  if (test("z1", z1, bench) == false)
141  return err;
142  vpRowVector z2 = vpRowVector(bench);
143  if (test("z2", z2, bench) == false)
144  return err;
145  }
146  {
147  vpRowVector v(3);
148  v[0] = 1;
149  v[1] = 2;
150  v[2] = 3;
151  std::vector<double> bench1;
152  bench1.push_back(3);
153  bench1.push_back(6);
154  bench1.push_back(9);
155 
156  vpRowVector w = v * 3;
157  // v is unchanged
158  // w is now equal to : [3 6 9]
159  if (test("w", w, bench1) == false)
160  return err;
161 
162  vpRowVector x(w);
163  if (test("x", x, bench1) == false)
164  return err;
165 
166  std::vector<float> bench2;
167  bench2.push_back(3);
168  bench2.push_back(6);
169  bench2.push_back(9);
170  vpRowVector y1(bench2);
171  if (test("y1", y1, bench1) == false)
172  return err;
173  vpRowVector y2 = vpRowVector(bench2);
174  if (test("y2", y2, bench1) == false)
175  return err;
176  }
177  {
178  vpRowVector r1(3, 1);
179  vpRowVector r2 = -r1;
180  std::vector<double> bench(3, -1);
181  // v contains [-1 -1 -1]
182  if (test("r2", r2, bench) == false)
183  return err;
184  r2.stack(-2);
185  bench.push_back(-2);
186  if (test("r2", r2, bench) == false)
187  return err;
188  vpRowVector r3 = vpRowVector::stack(r1, r2);
189  std::vector<double> bench3(7, 1);
190  bench3[3] = bench3[4] = bench3[5] = -1;
191  bench3[6] = -2;
192  if (test("r3", r3, bench3) == false)
193  return err;
194 
195  r1.stack(r2);
196  if (test("r1", r1, bench3) == false)
197  return err;
198  }
199  {
200  vpRowVector r1(3, 2);
201  vpRowVector r2(3, 4);
202  vpRowVector r = r1 + r2;
203  std::vector<double> bench(3, 6);
204  if (test("r", r, bench) == false)
205  return err;
206  r1 += r2;
207  if (test("r1", r1, bench) == false)
208  return err;
209  }
210  {
211  vpRowVector r1(3, 2);
212  vpRowVector r2(3, 4);
213  vpRowVector r = r1 - r2;
214  std::vector<double> bench(3, -2);
215  if (test("r", r, bench) == false)
216  return err;
217  r1 -= r2;
218  if (test("r1", r1, bench) == false)
219  return err;
220  }
221  {
222  vpRowVector r(5, 1);
223  r.clear();
224  r.resize(5);
225  r = 5;
226  std::vector<double> bench(5, 5);
227  if (test("r", r, bench) == false)
228  return err;
229  }
230  {
231  // Test mean, median and standard deviation against Matlab with rng(0) and
232  // rand(10,1)*10
233  vpRowVector r(10);
234  r[0] = 8.1472;
235  r[1] = 9.0579;
236  r[2] = 1.2699;
237  r[3] = 9.1338;
238  r[4] = 6.3236;
239  r[5] = 0.9754;
240  r[6] = 2.7850;
241  r[7] = 5.4688;
242  r[8] = 9.5751;
243  r[9] = 9.6489;
244 
245  std::cout << "** Test mean" << std::endl;
246  double res = vpRowVector::mean(r);
247  if (!vpMath::equal(res, 6.2386, 0.001)) {
248  std::cout << "Test fails: bad mean " << res << std::endl;
249  return err;
250  }
251 
252  std::cout << "** Test stdev" << std::endl;
253  res = vpRowVector::stdev(r);
254  if (!vpMath::equal(res, 3.2810, 0.001)) {
255  std::cout << "Test fails: bad stdev " << res << std::endl;
256  return err;
257  }
258 
259  std::cout << "** Test stdev(bessel)" << std::endl;
260  res = vpRowVector::stdev(r, true);
261  if (!vpMath::equal(res, 3.4585, 0.001)) {
262  std::cout << "Test fails: bad stdev(bessel) " << res << std::endl;
263  return err;
264  }
265 
266  std::cout << "** Test median" << std::endl;
267  res = vpRowVector::median(r);
268  if (!vpMath::equal(res, 7.2354, 0.001)) {
269  std::cout << "Test fails: bad median " << res << std::endl;
270  return err;
271  }
272 
273  // Test median with odd number of elements
274  std::cout << "** Test median (odd)" << std::endl;
275  r.stack(1.5761);
276  res = vpRowVector::median(r);
277  if (!vpMath::equal(res, 6.3236, 0.001)) {
278  std::cout << "Test fails: bad median (odd) " << res << std::endl;
279  return err;
280  }
281  std::cout << "r: [" << r << "]" << std::endl;
282  r.print(std::cout, 8, "r");
283  }
284 
285  {
286  std::cout << "** Test conversion to/from std::vector" << std::endl;
287  std::vector<double> std_vector(5);
288  for (size_t i = 0; i < std_vector.size(); i++) {
289  std_vector[i] = (double)i;
290  }
291  vpRowVector v(std_vector);
292  if (test("v", v, std_vector) == false)
293  return EXIT_FAILURE;
294 
295  std_vector.clear();
296  std_vector = v.toStdVector();
297  if (test("v", v, std_vector) == false)
298  return EXIT_FAILURE;
299  }
300  std::cout << "All tests succeed" << std::endl;
301  return EXIT_SUCCESS;
302 }
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
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
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:124
void resize(unsigned int i, bool flagNullify=true)
Definition: vpRowVector.h:287
static double mean(const vpRowVector &v)
void stack(double d)
void init(const vpRowVector &v, unsigned int c, unsigned int ncols)
void clear()
Definition: vpRowVector.h:150
vpRowVector & normalize()
static double median(const vpRowVector &v)
std::vector< double > toStdVector() const
static double stdev(const vpRowVector &v, bool useBesselCorrection=false)
vpRowVector extract(unsigned int c, unsigned int rowsize) const
Definition: vpRowVector.h:197
int print(std::ostream &s, unsigned int length, char const *intro=0) const