Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
testMatrix.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 vpMatrix functionalities.
32  */
33 
40 #include <visp3/core/vpConfig.h>
41 #include <visp3/core/vpDebug.h>
42 #include <visp3/core/vpGEMM.h>
43 #include <visp3/core/vpHomogeneousMatrix.h>
44 #include <visp3/core/vpMath.h>
45 #include <visp3/core/vpVelocityTwistMatrix.h>
46 
47 #include <stdio.h>
48 #include <stdlib.h>
49 
50 #include <iterator> // for std::back_inserter
51 
52 #ifdef ENABLE_VISP_NAMESPACE
53 using namespace VISP_NAMESPACE_NAME;
54 #endif
55 
56 namespace
57 {
58 bool test_memory(unsigned int nrows, unsigned int ncols, const vpMatrix &M, const std::string &matrix_name, bool pointer_is_null)
59 {
60  if (pointer_is_null) {
61  if (M.data) {
62  std::cerr << "Wrong data pointer (" << M.data << ") in matrix " << matrix_name << ": should be null" << std::endl;
63  }
64  }
65  else {
66  if (!M.data) {
67  std::cerr << "Wrong data pointer (" << M.data << ") in matrix " << matrix_name << ": should be non null" << std::endl;
68  return false;
69  }
70  }
71 
72  if (M.getRows() != nrows || M.getCols() != ncols) {
73  std::cerr << "Wrong matrix " << matrix_name << "(" << nrows << ", " << ncols << " size: "
74  << M.getRows() << " x " << M.getCols() << std::endl;
75  return false;
76  }
77  std::cout << "Test matrix " << matrix_name << " succeed" << std::endl;
78  return true;
79 }
80 
81 bool test(const std::string &s, const vpMatrix &M, const std::vector<double> &bench)
82 {
83  static unsigned int cpt = 0;
84  std::cout << "** Test " << ++cpt << std::endl;
85  std::cout << s << "(" << M.getRows() << "," << M.getCols() << ") = \n" << M << std::endl;
86  if (bench.size() != M.size()) {
87  std::cout << "Test fails: bad size wrt bench" << std::endl;
88  return false;
89  }
90  for (unsigned int i = 0; i < M.size(); i++) {
91  if (std::fabs(M.data[i] - bench[i]) > std::fabs(M.data[i]) * std::numeric_limits<double>::epsilon()) {
92  std::cout << "Test fails: bad content" << std::endl;
93  return false;
94  }
95  }
96 
97  return true;
98 }
99 
100 double getRandomValues(double min, double max) { return (max - min) * ((double)rand() / (double)RAND_MAX) + min; }
101 
102 bool equalMatrix(const vpMatrix &A, const vpMatrix &B, double tol = std::numeric_limits<double>::epsilon())
103 {
104  if (A.getRows() != B.getRows() || A.getCols() != B.getCols()) {
105  return false;
106  }
107 
108  for (unsigned int i = 0; i < A.getRows(); i++) {
109  for (unsigned int j = 0; j < A.getCols(); j++) {
110  if (!vpMath::equal(A[i][j], B[i][j], tol)) {
111  return false;
112  }
113  }
114  }
115 
116  return true;
117 }
118 
119 vpMatrix generateRandomMatrix(unsigned int rows, unsigned int cols, double min, double max)
120 {
121  vpMatrix M(rows, cols);
122 
123  for (unsigned int i = 0; i < M.getRows(); i++) {
124  for (unsigned int j = 0; j < M.getCols(); j++) {
125  M[i][j] = getRandomValues(min, max);
126  }
127  }
128 
129  return M;
130 }
131 
132 std::vector<double> computeHadamard(const std::vector<double> &v1, const std::vector<double> &v2)
133 {
134  std::vector<double> result;
135  std::transform(v1.begin(), v1.end(), v2.begin(), std::back_inserter(result), std::multiplies<double>());
136  return result;
137 }
138 } // namespace
139 
140 int main(int argc, char *argv[])
141 {
142  try {
143  bool ctest = true;
144  for (int i = 1; i < argc; i++) {
145  if (std::string(argv[i]) == "--benchmark") {
146  ctest = false;
147  }
148  }
149 
150  {
151  unsigned int nrows = 2, ncols = 3;
152  vpMatrix A(nrows, ncols);
153  if (test_memory(nrows, ncols, A, "A", false) == false) {
154  return EXIT_FAILURE;
155  }
156  vpMatrix B, C;
157  if (test_memory(0, 0, B, "B", true) == false) {
158  return EXIT_FAILURE;
159  }
160  if (test_memory(0, 0, C, "C", true)== false) {
161  return EXIT_FAILURE;
162  }
163  B = A;
164  if (test_memory(nrows, ncols, B, "B", false)== false) {
165  return EXIT_FAILURE;
166  }
167  B = C;
168  if (test_memory(0, 0, C, "C", true)== false) {
169  return EXIT_FAILURE;
170  }
171  }
172  {
173  const double val = 10.0;
174  vpMatrix M, M2(5, 5, val);
175  M.resize(5, 5, false, false);
176  M = val;
177  for (unsigned int i = 0; i < M.getRows(); i++) {
178  for (unsigned int j = 0; j < M.getCols(); j++) {
179  if (!vpMath::equal(M[i][j], val, std::numeric_limits<double>::epsilon())) {
180  std::cerr << "Issue with matrix assignment with value." << std::endl;
181  return EXIT_FAILURE;
182  }
183 
184  if (!vpMath::equal(M2[i][j], val, std::numeric_limits<double>::epsilon())) {
185  std::cerr << "Issue with matrix constructor initialized with value." << std::endl;
186  return EXIT_FAILURE;
187  }
188  }
189  }
190  }
191  {
192  // Test vpRotationMatrix construction
193  std::vector<double> bench(9, 0);
194  bench[2] = bench[4] = bench[6] = 1.;
195  vpMatrix M(3, 3);
196  M[2][0] = M[1][1] = M[0][2] = 1.;
197  vpRotationMatrix R1(M);
198  if (test("R1", static_cast<vpMatrix>(R1), bench) == false)
199  return EXIT_FAILURE;
200  vpRotationMatrix R2;
201  R2 = M;
202  if (test("R2", static_cast<vpMatrix>(R2), bench) == false)
203  return EXIT_FAILURE;
204  }
205  {
206  vpColVector c(6, 1);
207  vpRowVector r(6, 1);
208  std::vector<double> bench(6, 1);
209  vpMatrix M1(c);
210  if (test("M1", M1, bench) == false)
211  return EXIT_FAILURE;
212  vpMatrix M2(r);
213  if (test("M2", M2, bench) == false)
214  return EXIT_FAILURE;
215  }
216  {
217  vpMatrix M(4, 5);
218  int val = 0;
219  for (unsigned int i = 0; i < M.getRows(); i++) {
220  for (unsigned int j = 0; j < M.getCols(); j++) {
221  M[i][j] = val++;
222  }
223  }
224  std::cout << "M ";
225  M.print(std::cout, 4);
226 
227  vpMatrix N;
228  N.init(M, 0, 1, 2, 3);
229  std::cout << "N ";
230  N.print(std::cout, 4);
231  std::string header("My 4-by-5 matrix\nwith a second line");
232 
233  // Save matrix in text format
234  if (vpMatrix::saveMatrix("matrix.mat", M, false, header.c_str()))
235  std::cout << "Matrix saved in matrix.mat file" << std::endl;
236  else
237  return EXIT_FAILURE;
238 
239  // Load matrix in text format
240  vpMatrix M1;
241  char header_[100];
242  if (vpMatrix::loadMatrix("matrix.mat", M1, false, header_))
243  std::cout << "Matrix loaded from matrix.mat file with header \"" << header_ << "\": \n" << M1 << std::endl;
244  else
245  return EXIT_FAILURE;
246  if (header != std::string(header_)) {
247  std::cout << "Bad header in matrix.mat" << std::endl;
248  return EXIT_FAILURE;
249  }
250 
251  // Save matrix in binary format
252  if (vpMatrix::saveMatrix("matrix.bin", M, true, header.c_str()))
253  std::cout << "Matrix saved in matrix.bin file" << std::endl;
254  else
255  return EXIT_FAILURE;
256 
257  // Load matrix in binary format
258  if (vpMatrix::loadMatrix("matrix.bin", M1, true, header_))
259  std::cout << "Matrix loaded from matrix.bin file with header \"" << header_ << "\": \n" << M1 << std::endl;
260  else
261  return EXIT_FAILURE;
262  if (header != std::string(header_)) {
263  std::cout << "Bad header in matrix.bin" << std::endl;
264  return EXIT_FAILURE;
265  }
266 
267  // Save matrix in YAML format
268  if (vpMatrix::saveMatrixYAML("matrix.yml", M, header.c_str()))
269  std::cout << "Matrix saved in matrix.yml file" << std::endl;
270  else
271  return EXIT_FAILURE;
272 
273  // Read matrix in YAML format
274  vpMatrix M2;
275  if (vpMatrix::loadMatrixYAML("matrix.yml", M2, header_))
276  std::cout << "Matrix loaded from matrix.yml file with header \"" << header_ << "\": \n" << M2 << std::endl;
277  else
278  return EXIT_FAILURE;
279  if (header != std::string(header_)) {
280  std::cout << "Bad header in matrix.mat" << std::endl;
281  return EXIT_FAILURE;
282  }
283  }
284 
285  {
287  std::cout << "R: \n" << R << std::endl;
288  vpMatrix M1(R);
289  std::cout << "M1: \n" << M1 << std::endl;
290  vpMatrix M2(M1);
291  std::cout << "M2: \n" << M2 << std::endl;
292  vpMatrix M3 = static_cast<vpMatrix>(R);
293  std::cout << "M3: \n" << M3 << std::endl;
294  vpMatrix M4 = M1;
295  std::cout << "M4: \n" << M4 << std::endl;
296  }
297  {
298 
299  std::cout << "------------------------" << std::endl;
300  std::cout << "--- TEST PRETTY PRINT---" << std::endl;
301  std::cout << "------------------------" << std::endl;
302  vpMatrix M;
303  M.eye(4);
304 
305  std::cout << "call std::cout << M;" << std::endl;
306  std::cout << M << std::endl;
307 
308  std::cout << "call M.print (std::cout, 4);" << std::endl;
309  M.print(std::cout, 4);
310 
311  std::cout << "------------------------" << std::endl;
312  M.resize(3, 3);
313  M.eye(3);
314  M[1][0] = 1.235;
315  M[1][1] = 12.345;
316  M[1][2] = .12345;
317  std::cout << "call std::cout << M;" << std::endl;
318  std::cout << M << std::endl;
319  std::cout << "call M.print (std::cout, 6);" << std::endl;
320  M.print(std::cout, 6);
321  std::cout << std::endl;
322 
323  std::cout << "------------------------" << std::endl;
324  M[0][0] = -1.235;
325  M[1][0] = -12.235;
326 
327  std::cout << "call std::cout << M;" << std::endl;
328  std::cout << M << std::endl;
329 
330  std::cout << "call M.print (std::cout, 10);" << std::endl;
331  M.print(std::cout, 10);
332  std::cout << std::endl;
333 
334  std::cout << "call M.print (std::cout, 2);" << std::endl;
335  M.print(std::cout, 2);
336  std::cout << std::endl;
337 
338  std::cout << "------------------------" << std::endl;
339  M.resize(3, 3);
340  M.eye(3);
341  M[0][2] = -0.0000876;
342  std::cout << "call std::cout << M;" << std::endl;
343  std::cout << M << std::endl;
344 
345  std::cout << "call M.print (std::cout, 4);" << std::endl;
346  M.print(std::cout, 4);
347  std::cout << std::endl;
348  std::cout << "call M.print (std::cout, 6, \"M\");" << std::endl;
349  M.print(std::cout, 6, "M");
350  std::cout << std::endl;
351  std::cout << "call M.print (std::cout, 10, \"M\");" << std::endl;
352  M.print(std::cout, 10, "M");
353  std::cout << std::endl;
354 
355  M.resize(2, 3);
356  M[0][0] = -1;
357  M[0][1] = -2;
358  M[0][2] = -3;
359  M[1][0] = 4;
360  M[1][1] = 5.5;
361  M[1][2] = 6.0f;
362  std::cout << "call std::cout << M;" << std::endl;
363  std::cout << M << std::endl;
364  std::cout << "call M.print (std::cout, 5, \"M\");" << std::endl;
365  M.print(std::cout, 5, "M");
366  std::cout << std::endl;
367 
368  M.resize(2, 3);
369  M[0][0] = -1;
370  M[0][1] = -2;
371  M[0][2] = -3;
372  M[1][0] = 4;
373  M[1][1] = 5.;
374  M[1][2] = 6;
375  std::cout << "call std::cout << M;" << std::endl;
376  std::cout << M << std::endl;
377  std::cout << "call M.print (std::cout, 5, \"M\");" << std::endl;
378  M.print(std::cout, 5, "M");
379  std::cout << std::endl;
380 
381  std::cout << "------------------------" << std::endl;
382  std::cout << "--- TEST RESIZE --------" << std::endl;
383  std::cout << "------------------------" << std::endl;
384  std::cout << "5x5" << std::endl;
385  M.resize(5, 5, false);
386  std::cout << M << std::endl;
387  std::cout << "3x2" << std::endl;
388  M.resize(3, 2, false);
389  std::cout << M << std::endl;
390  std::cout << "2x2" << std::endl;
391  M.resize(2, 2, false);
392  std::cout << M << std::endl;
393  std::cout << "------------------------" << std::endl;
394 
396  vpMatrix A(1, 6), B;
397 
398  A = 1.0;
399  // vMe=1.0;
400  B = A * vMe;
401 
402  std::cout << "------------------------" << std::endl;
403  std::cout << "--- TEST vpRowVector * vpColVector" << std::endl;
404  std::cout << "------------------------" << std::endl;
405  vpRowVector r(3);
406  r[0] = 2;
407  r[1] = 3;
408  r[2] = 4;
409 
410  vpColVector c(3);
411  c[0] = 1;
412  c[1] = 2;
413  c[2] = -1;
414 
415  double rc = r * c;
416 
417  r.print(std::cout, 2, "r");
418  c.print(std::cout, 2, "c");
419  std::cout << "r * c = " << rc << std::endl;
420 
421  std::cout << "------------------------" << std::endl;
422  std::cout << "--- TEST vpRowVector * vpMatrix" << std::endl;
423  std::cout << "------------------------" << std::endl;
424  M.resize(3, 3);
425  M.eye(3);
426 
427  M[1][0] = 1.5;
428  M[2][0] = 2.3;
429 
430  vpRowVector rM = r * M;
431 
432  r.print(std::cout, 2, "r");
433  M.print(std::cout, 10, "M");
434  std::cout << "r * M = " << rM << std::endl;
435 
436  std::cout << "------------------------" << std::endl;
437  std::cout << "--- TEST vpGEMM " << std::endl;
438  std::cout << "------------------------" << std::endl;
439  M.resize(3, 3);
440  M.eye(3);
441  vpMatrix N(3, 3);
442  N[0][0] = 2;
443  N[1][0] = 1.2;
444  N[1][2] = 0.6;
445  N[2][2] = 0.25;
446 
447  vpMatrix C(3, 3);
448  C.eye(3);
449 
450  vpMatrix D;
451 
452  // realise the operation D = 2 * M^T * N + 3 C
453  vpGEMM(M, N, 2, C, 3, D, VP_GEMM_A_T);
454  std::cout << D << std::endl;
455  }
456 
457  {
458  std::cout << "------------------------" << std::endl;
459  std::cout << "--- TEST vpMatrix insert() with same colNum " << std::endl;
460  std::cout << "------------------------" << std::endl;
461  unsigned int nb = ctest ? 10 : 100; // 10000;
462  const unsigned int size = ctest ? 10 : 100;
463 
464  vpMatrix m_big(nb *size, 6);
465  std::vector<vpMatrix> submatrices(nb);
466  for (size_t cpt = 0; cpt < submatrices.size(); cpt++) {
467  vpMatrix m(size, 6);
468 
469  for (unsigned int i = 0; i < m.getRows(); i++) {
470  for (unsigned int j = 0; j < m.getCols(); j++) {
471  m[i][j] = getRandomValues(-100.0, 100.0);
472  }
473  }
474 
475  submatrices[cpt] = m;
476  }
477 
478  double t = vpTime::measureTimeMs();
479  for (unsigned int i = 0; i < nb; i++) {
480  m_big.insert(submatrices[(size_t)i], i * size, 0);
481  }
482  t = vpTime::measureTimeMs() - t;
483  std::cout << "Matrix insert(): " << t << " ms" << std::endl;
484 
485  for (unsigned int cpt = 0; cpt < nb; cpt++) {
486  for (unsigned int i = 0; i < size; i++) {
487  for (unsigned int j = 0; j < 6; j++) {
488  if (!vpMath::equal(m_big[cpt * size + i][j], submatrices[(size_t)cpt][i][j],
489  std::numeric_limits<double>::epsilon())) {
490  std::cerr << "Problem with vpMatrix insert()!" << std::endl;
491  return EXIT_FAILURE;
492  }
493  }
494  }
495  }
496 
497  // Try to insert empty matrices
498  vpMatrix m1(2, 3), m2, m3;
499  m1.insert(m2, 0, 0);
500  m3.insert(m2, 0, 0);
501 
502  std::cout << "Insert empty matrices:" << std::endl;
503  std::cout << "m1:\n" << m1 << std::endl;
504  std::cout << "m2:\n" << m2 << std::endl;
505  std::cout << "m3:\n" << m3 << std::endl;
506 
507  std::cout << "\n------------------------" << std::endl;
508  std::cout << "--- TEST vpMatrix stack()" << std::endl;
509  std::cout << "------------------------" << std::endl;
510 
511  {
512  vpMatrix L, L2(2, 6);
513  L2 = 2;
514  L.stack(L2);
515  std::cout << "L:\n" << L << std::endl;
516  L2.resize(3, 6);
517  L2 = 3;
518  L.stack(L2);
519  std::cout << "L:\n" << L << std::endl;
520  }
521 
522  {
523  vpMatrix m_big_stack;
524  t = vpTime::measureTimeMs();
525  for (unsigned int i = 0; i < nb; i++) {
526  m_big_stack.stack(submatrices[(size_t)i]);
527  }
528  t = vpTime::measureTimeMs() - t;
529  std::cout << "Matrix stack(): " << t << " ms" << std::endl;
530 
531  if (!equalMatrix(m_big, m_big_stack)) {
532  std::cerr << "Problem with vpMatrix stack()!" << std::endl;
533  return EXIT_FAILURE;
534  }
535  }
536 
537  std::cout << "\n------------------------" << std::endl;
538  std::cout << "--- TEST vpMatrix stack(vpRowVector)" << std::endl;
539  std::cout << "------------------------" << std::endl;
540 
541  vpMatrix m_big_stack = generateRandomMatrix(10000, ctest ? 10 : 100, -1000.0, 1000.0);
542  std::cout << "m_big_stack: " << m_big_stack.getRows() << "x" << m_big_stack.getCols() << std::endl;
543 
544  vpMatrix m_big_stack_row;
545  t = vpTime::measureTimeMs();
546  for (unsigned int i = 0; i < m_big_stack.getRows(); i++) {
547  m_big_stack_row.stack(m_big_stack.getRow(i));
548  }
549  t = vpTime::measureTimeMs() - t;
550  std::cout << "Matrix stack(vpRowVector): " << t << " ms" << std::endl;
551 
552  if (!equalMatrix(m_big_stack, m_big_stack_row)) {
553  std::cerr << "Problem with vpMatrix stack(vpRowVector)!" << std::endl;
554  return EXIT_FAILURE;
555  }
556 
557  std::cout << "\n------------------------" << std::endl;
558  std::cout << "--- TEST vpMatrix stack(vpColVector)" << std::endl;
559  std::cout << "------------------------" << std::endl;
560 
561  vpMatrix m_big_stack_col;
562  t = vpTime::measureTimeMs();
563  for (unsigned int j = 0; j < m_big_stack.getCols(); j++) {
564  m_big_stack_col.stack(m_big_stack.getCol(j));
565  }
566  t = vpTime::measureTimeMs() - t;
567  std::cout << "Matrix stack(vpColVector): " << t << " ms" << std::endl;
568 
569  if (!equalMatrix(m_big_stack, m_big_stack_col)) {
570  std::cerr << "Problem with vpMatrix stack(vpColVector)!" << std::endl;
571  return EXIT_FAILURE;
572  }
573 
574  std::cout << "\n------------------------" << std::endl;
575  std::cout << "--- TEST vpMatrix::stack()" << std::endl;
576  std::cout << "------------------------" << std::endl;
577 
578  {
579  vpMatrix L, L2(2, 6), L_tmp;
580  L2 = 2;
581  vpMatrix::stack(L_tmp, L2, L);
582  std::cout << "L:\n" << L << std::endl;
583  L2.resize(3, 6);
584  L2 = 3;
585  L_tmp = L;
586  vpMatrix::stack(L_tmp, L2, L);
587  std::cout << "L:\n" << L << std::endl;
588  }
589 
590  {
591  vpMatrix m_big_stack_static, m_big_stack_static_tmp;
592  t = vpTime::measureTimeMs();
593  for (unsigned int i = 0; i < nb; i++) {
594  vpMatrix::stack(m_big_stack_static_tmp, submatrices[(size_t)i], m_big_stack_static);
595  m_big_stack_static_tmp = m_big_stack_static;
596  }
597  t = vpTime::measureTimeMs() - t;
598  std::cout << "Matrix::stack(): " << t << " ms" << std::endl;
599 
600  if (!equalMatrix(m_big, m_big_stack_static)) {
601  std::cerr << "Problem with vpMatrix::stack()!" << std::endl;
602  return EXIT_FAILURE;
603  }
604  }
605 
606  std::cout << "\n------------------------" << std::endl;
607  std::cout << "--- TEST vpMatrix::stack(vpMatrix, vpRowVector, vpMatrix)" << std::endl;
608  std::cout << "------------------------" << std::endl;
609 
610  vpMatrix m_big_stack_static = generateRandomMatrix(ctest ? 100 : 1000, ctest ? 10 : 100, -1000.0, 1000.0);
611  std::cout << "m_big_stack_static: " << m_big_stack_static.getRows() << "x" << m_big_stack_static.getCols()
612  << std::endl;
613 
614  vpMatrix m_big_stack_static_row, m_big_stack_static_row_tmp;
615  t = vpTime::measureTimeMs();
616  for (unsigned int i = 0; i < m_big_stack_static.getRows(); i++) {
617  vpMatrix::stack(m_big_stack_static_row_tmp, m_big_stack_static.getRow(i), m_big_stack_static_row);
618  m_big_stack_static_row_tmp = m_big_stack_static_row;
619  }
620  t = vpTime::measureTimeMs() - t;
621  std::cout << "Matrix::stack(vpMatrix, vpRowVector, vpMatrix): " << t << " ms" << std::endl;
622 
623  if (!equalMatrix(m_big_stack_static, m_big_stack_static_row)) {
624  std::cerr << "Problem with vpMatrix::stack(vpMatrix, vpRowVector, "
625  "vpMatrix)!"
626  << std::endl;
627  return EXIT_FAILURE;
628  }
629 
630  std::cout << "\n------------------------" << std::endl;
631  std::cout << "--- TEST vpMatrix::stack(vpMatrix, vpColVector, vpMatrix)" << std::endl;
632  std::cout << "------------------------" << std::endl;
633 
634  vpMatrix m_big_stack_static_col, m_big_stack_static_col_tmp;
635  t = vpTime::measureTimeMs();
636  for (unsigned int j = 0; j < m_big_stack_static.getCols(); j++) {
637  vpMatrix::stack(m_big_stack_static_col_tmp, m_big_stack_static.getCol(j), m_big_stack_static_col);
638  m_big_stack_static_col_tmp = m_big_stack_static_col;
639  }
640  t = vpTime::measureTimeMs() - t;
641  std::cout << "Matrix::stack(vpMatrix, vpColVector, vpMatrix): " << t << " ms" << std::endl;
642 
643  if (!equalMatrix(m_big_stack_static, m_big_stack_static_col)) {
644  std::cerr << "Problem with vpMatrix::stack(vpMatrix, vpColVector, "
645  "vpMatrix)!"
646  << std::endl;
647  return EXIT_FAILURE;
648  }
649  }
650 
651  {
652  vpMatrix m1(11, 9), m2(3, 4);
653  for (unsigned int i = 0; i < m2.getRows(); i++) {
654  for (unsigned int j = 0; j < m2.getCols(); j++) {
655  m2[i][j] = getRandomValues(-100.0, 100.0);
656  }
657  }
658 
659  unsigned int offset_i = 4, offset_j = 3;
660  m1.insert(m2, offset_i, offset_j);
661 
662  for (unsigned int i = 0; i < m2.getRows(); i++) {
663  for (unsigned int j = 0; j < m2.getCols(); j++) {
664  if (!vpMath::equal(m1[i + offset_i][j + offset_j], m2[i][j], std::numeric_limits<double>::epsilon())) {
665  std::cerr << "Problem with vpMatrix insert()!" << std::endl;
666  return EXIT_FAILURE;
667  }
668  }
669  }
670 
671  offset_i = 4;
672  offset_j = 5;
673  m1.insert(m2, offset_i, offset_j);
674 
675  for (unsigned int i = 0; i < m2.getRows(); i++) {
676  for (unsigned int j = 0; j < m2.getCols(); j++) {
677  if (!vpMath::equal(m1[i + offset_i][j + offset_j], m2[i][j], std::numeric_limits<double>::epsilon())) {
678  std::cerr << "Problem with vpMatrix insert()!" << std::endl;
679  return EXIT_FAILURE;
680  }
681  }
682  }
683 
684  offset_i = 8;
685  offset_j = 5;
686  m1.insert(m2, offset_i, offset_j);
687 
688  for (unsigned int i = 0; i < m2.getRows(); i++) {
689  for (unsigned int j = 0; j < m2.getCols(); j++) {
690  if (!vpMath::equal(m1[i + offset_i][j + offset_j], m2[i][j], std::numeric_limits<double>::epsilon())) {
691  std::cerr << "Problem with vpMatrix insert()!" << std::endl;
692  return EXIT_FAILURE;
693  }
694  }
695  }
696  }
697 
698  {
699  std::cout << "\n------------------------" << std::endl;
700  std::cout << "--- TEST vpMatrix::juxtaposeMatrices()" << std::endl;
701  std::cout << "------------------------" << std::endl;
702 
703  vpMatrix A(5, 6), B(5, 4);
704  for (unsigned int i = 0; i < A.getRows(); i++) {
705  for (unsigned int j = 0; j < A.getCols(); j++) {
706  A[i][j] = i * A.getCols() + j;
707 
708  if (j < B.getCols()) {
709  B[i][j] = (i * B.getCols() + j) * 10;
710  }
711  }
712  }
713 
714  vpMatrix juxtaposeM;
715  vpMatrix::juxtaposeMatrices(A, B, juxtaposeM);
716  std::cout << "juxtaposeM:\n" << juxtaposeM << std::endl;
717  }
718 
719 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
720  {
721  std::vector<vpMatrix> vec_mat;
722  vec_mat.emplace_back(5, 5);
723 
724  vpMatrix A(4, 4), B(4, 4);
725  A = 1;
726  B = 2;
727  vpMatrix res = A + B;
728  std::cout << "\n1) A+B:\n" << res << std::endl;
729 
730  vpMatrix res2;
731  res2 = A + B;
732  std::cout << "\n2) A+B:\n" << res2 << std::endl;
733  }
734 #endif
735 
736  {
737  std::cout << "\n------------------------" << std::endl;
738  std::cout << "--- TEST vpMatrix::hadamard()" << std::endl;
739  std::cout << "------------------------" << std::endl;
740 
741  vpMatrix M1(3, 5), M2(3, 5);
742  for (unsigned int i = 0; i < M1.size(); i++) {
743  M1.data[i] = i;
744  M2.data[i] = i + 2;
745  }
746 
747  // Reference
748  std::vector<double> references = computeHadamard(std::vector<double>(M1.data, M1.data + M1.size()),
749  std::vector<double>(M2.data, M2.data + M2.size()));
750 
751  std::cout << "M1:\n" << M1 << std::endl;
752  std::cout << "\nM2:\n" << M2 << std::endl;
753  M2 = M1.hadamard(M2);
754  std::cout << "\nRes:\n" << M2 << std::endl;
755 
756  if (!test("M2", M2, references)) {
757  std::cerr << "Error with Hadamard product" << std::endl;
758  return EXIT_FAILURE;
759  }
760  }
761 
762  {
763  std::cout << "\n------------------------" << std::endl;
764  std::cout << "--- TEST vpMatrix::stackColums()" << std::endl;
765  std::cout << "------------------------" << std::endl;
766  vpMatrix M(3, 5);
767  for (unsigned int j = 0; j < M.getCols(); j++) {
768  for (unsigned int i = 0; i < M.getRows(); i++) {
769  M[i][j] = i + j * M.getRows();
770  }
771  }
772  std::cout << "M:\n" << M << std::endl;
773  vpColVector v = M.stackColumns();
774  std::cout << "Column stack: " << v.t() << std::endl;
775  if (M.size() != v.size()) {
776  std::cerr << "Problem in vpMatrix::stackColumns(): size differ" << std::endl;
777  return EXIT_FAILURE;
778  }
779  for (unsigned int i = 0; i < v.size(); i++) {
780  if (std::fabs(v[i] - static_cast<double>(i)) > std::numeric_limits<double>::epsilon()) {
781  std::cerr << "Problem in vpMatrix::stackColumns(): content differ" << std::endl;
782  return EXIT_FAILURE;
783  }
784  }
785  }
786 
787  {
788  std::cout << "\n------------------------" << std::endl;
789  std::cout << "--- TEST vpMatrix::stackRows()" << std::endl;
790  std::cout << "------------------------" << std::endl;
791  vpMatrix M(3, 5);
792  for (unsigned int i = 0; i < M.getRows(); i++) {
793  for (unsigned int j = 0; j < M.getCols(); j++) {
794  M[i][j] = i * M.getCols() + j;
795  }
796  }
797  std::cout << "M:\n" << M << std::endl;
798  vpRowVector v = M.stackRows();
799  std::cout << "Rows stack: " << v << std::endl;
800  if (M.size() != v.size()) {
801  std::cerr << "Problem in vpMatrix::stackRows(): size differ" << std::endl;
802  return EXIT_FAILURE;
803  }
804  for (unsigned int i = 0; i < v.size(); i++) {
805  if (std::fabs(v[i] - static_cast<double>(i)) > std::numeric_limits<double>::epsilon()) {
806  std::cerr << "Problem in vpMatrix::stackRows(): content differ" << std::endl;
807  return EXIT_FAILURE;
808  }
809  }
810  }
811 
812  {
813  std::cout << "\n------------------------" << std::endl;
814  std::cout << "--- TEST vpMatrix::getCol()" << std::endl;
815  std::cout << "------------------------" << std::endl;
816  vpMatrix A(4, 4);
817  for (unsigned int i = 0; i < A.getRows(); i++)
818  for (unsigned int j = 0; j < A.getCols(); j++)
819  A[i][j] = i * A.getCols() + j;
820 
821  {
822  vpColVector cv = A.getCol(1, 1, 3);
823  vpColVector ref;
824  ref << 5, 9, 13;
825  if (cv != ref) {
826  std::cerr << "Problem in vpMatrix::getCol(): values are different" << std::endl;
827  return EXIT_FAILURE;
828  }
829  }
830  {
831  vpColVector cv = A.getCol(1);
832  vpColVector ref;
833  ref << 1, 5, 9, 13;
834  if (cv != ref) {
835  std::cerr << "Problem in vpMatrix::getCol(): values are different" << std::endl;
836  return EXIT_FAILURE;
837  }
838  }
839  }
840 
841  {
842  std::cout << "\n------------------------" << std::endl;
843  std::cout << "--- TEST vpMatrix::getRow()" << std::endl;
844  std::cout << "------------------------" << std::endl;
845  vpMatrix A(4, 4);
846  for (unsigned int i = 0; i < A.getRows(); i++)
847  for (unsigned int j = 0; j < A.getCols(); j++)
848  A[i][j] = i * A.getCols() + j;
849 
850  {
851  vpRowVector rv = A.getRow(1, 1, 3);
852  vpRowVector ref;
853  ref << 5, 6, 7;
854  if (rv != ref) {
855  std::cerr << "Problem in vpMatrix::getRow(): values are different" << std::endl;
856  return EXIT_FAILURE;
857  }
858  }
859  {
860  vpRowVector rv = A.getRow(1);
861  vpRowVector ref;
862  ref << 4, 5, 6, 7;
863  if (rv != ref) {
864  std::cerr << "Problem in vpMatrix::getRow(): values are different" << std::endl;
865  return EXIT_FAILURE;
866  }
867  }
868  }
869 
870  {
871  std::cout << "\n------------------------" << std::endl;
872  std::cout << "--- TEST vpMatrix::getDiag()" << std::endl;
873  std::cout << "------------------------" << std::endl;
874  vpMatrix A(3, 4);
875  for (unsigned int i = 0; i < A.getRows(); i++)
876  for (unsigned int j = 0; j < A.getCols(); j++)
877  A[i][j] = i * A.getCols() + j;
878 
879  vpColVector diag = A.getDiag();
880  vpColVector ref;
881  ref << 0.0, 5.0, 10.0;
882  if (diag != ref) {
883  std::cerr << "Problem in vpMatrix::getDiag(): values are different" << std::endl;
884  return EXIT_FAILURE;
885  }
886  }
887 
888  std::cout << "\nAll tests succeeded" << std::endl;
889  return EXIT_SUCCESS;
890  }
891  catch (const vpException &e) {
892  std::cout << "Catch an exception: " << e << std::endl;
893  return EXIT_FAILURE;
894  }
895 }
unsigned int getCols() const
Definition: vpArray2D.h:337
Type * data
Address of the first element of the data array.
Definition: vpArray2D.h:148
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:362
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
vpRowVector t() const
error that can be emitted by ViSP classes.
Definition: vpException.h:60
static double rad(double deg)
Definition: vpMath.h:129
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
vpMatrix hadamard(const vpMatrix &m) const
int print(std::ostream &s, unsigned int length, const std::string &intro="") const
Definition: vpMatrix.cpp:824
void init(const vpMatrix &M, unsigned int r, unsigned int c, unsigned int nrows, unsigned int ncols)
Definition: vpMatrix.cpp:357
static bool loadMatrix(const std::string &filename, vpArray2D< double > &M, bool binary=false, char *header=nullptr)
Definition: vpMatrix.h:829
void stack(const vpMatrix &A)
static vpMatrix juxtaposeMatrices(const vpMatrix &A, const vpMatrix &B)
Definition: vpMatrix.cpp:757
vpRowVector getRow(unsigned int i) const
Definition: vpMatrix.cpp:590
vpColVector getDiag() const
Definition: vpMatrix.cpp:687
vpColVector getCol(unsigned int j) const
Definition: vpMatrix.cpp:548
void insert(const vpMatrix &A, unsigned int r, unsigned int c)
Definition: vpMatrix.cpp:1133
static bool saveMatrixYAML(const std::string &filename, const vpArray2D< double > &M, const char *header="")
Definition: vpMatrix.h:1065
static bool loadMatrixYAML(const std::string &filename, vpArray2D< double > &M, char *header=nullptr)
Definition: vpMatrix.h:908
static bool saveMatrix(const std::string &filename, const vpArray2D< double > &M, bool binary=false, const char *header="")
Definition: vpMatrix.h:985
Implementation of a rotation matrix and operations on such kind of matrices.
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:124
void resize(unsigned int i, bool flagNullify=true)
Definition: vpRowVector.h:287
VISP_EXPORT double measureTimeMs()