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