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