Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
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
39
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
48using namespace VISP_NAMESPACE_NAME;
49#endif
50
51namespace
52{
53bool 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
72double getRandomValues(double min, double max) { return (max - min) * (static_cast<double>(rand()) / static_cast<double>(RAND_MAX)) + min; }
73} // namespace
74
75int 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 {
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] = static_cast<double>(i);
118 bench1[i] = static_cast<double>(i);
119 }
120 if (test("v", v, bench1) == false)
121 return EXIT_FAILURE;
122
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(static_cast<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;
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[static_cast<size_t>(i)]);
335 }
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[static_cast<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] = static_cast<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}
Implementation of column vector and the associated operations.
vpColVector extract(unsigned int r, unsigned int colsize) const
static double median(const vpColVector &v)
void stack(double d)
static double mean(const vpColVector &v)
vpRowVector t() const
static double stdev(const vpColVector &v, bool useBesselCorrection=false)
void insert(unsigned int i, const vpColVector &v)
static bool equal(double x, double y, double threshold=0.001)
Definition vpMath.h:470
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
VISP_EXPORT double measureTimeMs()