44#include <visp3/core/vpColVector.h>
45#include <visp3/core/vpMatrix.h>
46#include <visp3/core/vpTime.h>
47#include <visp3/io/vpParseArgv.h>
50#define GETOPTARGS "cdn:i:pf:R:C:vh"
52#ifdef ENABLE_VISP_NAMESPACE
56void usage(
const char *name,
const char *badparam);
57bool getOptions(
int argc,
const char **argv,
unsigned int &nb_matrices,
unsigned int &nb_iterations,
58 bool &use_plot_file, std::string &plotfile,
unsigned int &nbrows,
unsigned int &nbcols,
bool &verbose);
62vpMatrix make_random_matrix(
unsigned int nbrows,
unsigned int nbcols);
63void create_bench_random_matrix(
unsigned int nb_matrices,
unsigned int nb_rows,
unsigned int nb_cols,
bool verbose,
64 std::vector<vpMatrix> &bench);
65int test_pseudo_inverse(
const std::vector<vpMatrix> &A,
const std::vector<vpMatrix> &Api);
66int test_pseudo_inverse(
const std::vector<vpMatrix> &A,
const std::vector<vpMatrix> &Api,
67 const std::vector<vpColVector> &sv,
const std::vector<vpMatrix> &imA,
68 const std::vector<vpMatrix> &imAt,
const std::vector<vpMatrix> &kerAt);
69int test_pseudo_inverse_default(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time);
70void save_time(
const std::string &method,
unsigned int nrows,
unsigned int ncols,
bool verbose,
bool use_plot_file,
71 std::ofstream &of,
const std::vector<double> &time);
72#if defined(VISP_HAVE_EIGEN3)
73int test_pseudo_inverse_eigen3(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time);
75#if defined(VISP_HAVE_LAPACK)
76int test_pseudo_inverse_lapack(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time);
78#if defined(VISP_HAVE_OPENCV)
79int test_pseudo_inverse_opencv(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time);
88void usage(
const char *name,
const char *badparam)
91Test matrix pseudo-inverse.\n\
92Outputs a comparison of the results obtained by supported 3rd parties.\n\
95 %s [-n <number of matrices>] [-f <plot filename>]\n\
96 [-R <number of rows>] [-C <number of columns>]\n\
97 [-i <number of iterations>] [-p] [-h]\n",
102 -n <number of matrices> \n\
103 Number of matrices inverted during each test loop.\n\
105 -i <number of iterations> \n\
106 Number of iterations of the test.\n\
108 -f <plot filename> \n\
109 Set output path for plot output.\n\
110 The plot logs the times of \n\
111 the different inversion methods: \n\
112 QR,LU,Cholesky and Pseudo-inverse.\n\
114 -R <number of rows>\n\
115 Number of rows of the automatically generated matrices \n\
118 -C <number of columns>\n\
119 Number of colums of the automatically generated matrices \n\
123 Plot into filename in the gnuplot format. \n\
124 If this option is used, tests results will be logged \n\
125 into a filename specified with -f.\n\
128 Print the help.\n\n");
131 fprintf(stderr,
"ERROR: \n");
132 fprintf(stderr,
"\nBad parameter [%s]\n", badparam);
141bool getOptions(
int argc,
const char **argv,
unsigned int &nb_matrices,
unsigned int &nb_iterations,
142 bool &use_plot_file, std::string &plotfile,
unsigned int &nbrows,
unsigned int &nbcols,
bool &verbose)
150 usage(argv[0],
nullptr);
153 nb_matrices =
static_cast<unsigned int>(atoi(optarg_));
156 nb_iterations =
static_cast<unsigned int>(atoi(optarg_));
160 use_plot_file =
true;
163 use_plot_file =
true;
166 nbrows =
static_cast<unsigned int>(atoi(optarg_));
169 nbcols =
static_cast<unsigned int>(atoi(optarg_));
180 usage(argv[0], optarg_);
185 if ((c == 1) || (c == -1)) {
187 usage(argv[0],
nullptr);
188 std::cerr <<
"ERROR: " << std::endl;
189 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
196vpMatrix make_random_matrix(
unsigned int nbrows,
unsigned int nbcols)
201 for (
unsigned int i = 0;
i < A.
getRows();
i++) {
202 for (
unsigned int j = 0;
j < A.
getCols();
j++) {
203 A[
i][
j] =
static_cast<double>(rand()) /
static_cast<double>(RAND_MAX);
210void create_bench_random_matrix(
unsigned int nb_matrices,
unsigned int nb_rows,
unsigned int nb_cols,
bool verbose,
211 std::vector<vpMatrix> &bench)
214 std::cout <<
"Create a bench of " << nb_matrices <<
" " << nb_rows <<
" by " << nb_cols <<
" matrices" << std::endl;
216 for (
unsigned int i = 0;
i < nb_matrices;
i++) {
217 vpMatrix M = make_random_matrix(nb_rows, nb_cols);
222int test_pseudo_inverse(
const std::vector<vpMatrix> &A,
const std::vector<vpMatrix> &Api)
224 double allowed_error = 1
e-3;
228 for (
unsigned int i = 0;
i < A.size();
i++) {
229 error = (A[
i] * Api[
i] * A[
i] - A[
i]).frobeniusNorm();
230 if (error > allowed_error) {
231 std::cout <<
"Bad pseudo-inverse [" <<
i <<
"] test A A^+ A = A: euclidean norm: " <<
error << std::endl;
234 error = (Api[
i] * A[
i] * Api[
i] - Api[
i]).frobeniusNorm();
235 if (error > allowed_error) {
236 std::cout <<
"Bad pseudo-inverse [" <<
i <<
"] test A^+ A A^+ = A^+: euclidean norm: " <<
error << std::endl;
239 A_Api = A[
i] * Api[
i];
241 if (error > allowed_error) {
242 std::cout <<
"Bad pseudo-inverse [" <<
i <<
"] test (A A^+)^T = A A^+: euclidean norm: " <<
error << std::endl;
245 Api_A = Api[
i] * A[
i];
247 if (error > allowed_error) {
248 std::cout <<
"Bad pseudo-inverse [" <<
i <<
"] test (A^+ A )^T = A^+ A: euclidean norm: " <<
error << std::endl;
256int test_pseudo_inverse(
const std::vector<vpMatrix> &A,
const std::vector<vpMatrix> &Api,
257 const std::vector<vpColVector> &sv,
const std::vector<vpMatrix> &imA,
258 const std::vector<vpMatrix> &imAt,
const std::vector<vpMatrix> &kerAt)
260 double allowed_error = 1
e-3;
262 if (test_pseudo_inverse(A, Api) == EXIT_FAILURE) {
267 for (
unsigned int i = 0;
i < kerAt.size();
i++) {
268 if (kerAt[i].size()) {
271 if (error > allowed_error) {
272 std::cout <<
"Bad kernel [" <<
i <<
"]: euclidean norm: " <<
error << std::endl;
279 for (
unsigned int i = 0;
i < kerAt.size();
i++) {
280 unsigned int rank = imA[
i].getCols();
281 vpMatrix U, S(rank, A[i].getCols()), Vt(A[i].getCols(), A[i].getCols());
284 for (
unsigned int j = 0;
j < rank;
j++)
288 Vt.insert(kerAt[i], imAt[i].getCols(), 0);
290 double error = (U * S * Vt - A[
i]).frobeniusNorm();
292 if (error > allowed_error) {
293 std::cout <<
"Bad imA, imAt, sv, kerAt [" <<
i <<
"]: euclidean norm: " <<
error << std::endl;
301int test_pseudo_inverse_default(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time)
304 std::cout <<
"Test pseudo-inverse using default 3rd party" << std::endl;
306 std::cout <<
" Pseudo-inverse on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
308 size_t size = bench.size();
309 std::vector<vpMatrix> PI(size), imA(size), imAt(size), kerAt(size);
310 std::vector<vpColVector> sv(size);
311 int ret = EXIT_SUCCESS;
316 for (
unsigned int i = 0;
i < bench.size();
i++) {
317 PI[
i] = bench[
i].pseudoInverse();
320 for (
unsigned int i = 0;
i < time.size();
i++) {
321 ret += test_pseudo_inverse(bench, PI);
326 for (
unsigned int i = 0;
i < bench.size();
i++) {
327 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
328 unsigned int rank = bench[
i].pseudoInverse(PI[i]);
329 if (rank != rank_bench) {
331 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
337 for (
unsigned int i = 0;
i < time.size();
i++) {
338 ret += test_pseudo_inverse(bench, PI);
343 for (
unsigned int i = 0;
i < bench.size();
i++) {
344 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
345 unsigned int rank = bench[
i].pseudoInverse(PI[i], sv[i]);
346 if (rank != rank_bench) {
348 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
354 for (
unsigned int i = 0;
i < time.size();
i++) {
355 ret += test_pseudo_inverse(bench, PI);
360 for (
unsigned int i = 0;
i < bench.size();
i++) {
361 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
362 unsigned int rank = bench[
i].pseudoInverse(PI[i], sv[i], 1e-6, imA[i], imAt[i]);
363 if (rank != rank_bench) {
365 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
371 for (
unsigned int i = 0;
i < time.size();
i++) {
372 ret += test_pseudo_inverse(bench, PI);
377 for (
unsigned int i = 0;
i < bench.size();
i++) {
378 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
379 unsigned int rank = bench[
i].pseudoInverse(PI[i], sv[i], 1e-6, imA[i], imAt[i], kerAt[i]);
380 if (rank != rank_bench) {
382 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
388 for (
unsigned int i = 0;
i < time.size();
i++) {
389 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
396 for (
unsigned int i = 0;
i < bench.size();
i++) {
397 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
398 PI[
i] = bench[
i].pseudoInverse(
static_cast<int>(rank_bench));
401 for (
unsigned int i = 0;
i < time.size();
i++) {
402 ret += test_pseudo_inverse(bench, PI);
407 for (
unsigned int i = 0;
i < bench.size();
i++) {
408 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
409 unsigned int rank = bench[
i].pseudoInverse(PI[i],
static_cast<int>(rank_bench));
410 if (rank != rank_bench) {
412 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
418 for (
unsigned int i = 0;
i < time.size();
i++) {
419 ret += test_pseudo_inverse(bench, PI);
424 for (
unsigned int i = 0;
i < bench.size();
i++) {
425 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
426 unsigned int rank = bench[
i].pseudoInverse(PI[i], sv[i],
static_cast<int>(rank_bench));
427 if (rank != rank_bench) {
429 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
435 for (
unsigned int i = 0;
i < time.size();
i++) {
436 ret += test_pseudo_inverse(bench, PI);
441 for (
unsigned int i = 0;
i < bench.size();
i++) {
442 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
443 unsigned int rank = bench[
i].pseudoInverse(PI[i], sv[i],
static_cast<int>(rank_bench), imA[i], imAt[i]);
444 if (rank != rank_bench) {
446 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
452 for (
unsigned int i = 0;
i < time.size();
i++) {
453 ret += test_pseudo_inverse(bench, PI);
458 for (
unsigned int i = 0;
i < bench.size();
i++) {
459 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
460 unsigned int rank = bench[
i].pseudoInverse(PI[i], sv[i],
static_cast<int>(rank_bench), imA[i], imAt[i], kerAt[i]);
461 if (rank != rank_bench) {
463 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
469 for (
unsigned int i = 0;
i < time.size();
i++) {
470 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
476#if defined(VISP_HAVE_EIGEN3)
477int test_pseudo_inverse_eigen3(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time)
480 std::cout <<
"Test pseudo-inverse using Eigen3 3rd party" << std::endl;
482 std::cout <<
" Pseudo-inverse on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
484 size_t size = bench.size();
485 std::vector<vpMatrix> PI(size), imA(size), imAt(size), kerAt(size);
486 std::vector<vpColVector> sv(size);
487 int ret = EXIT_SUCCESS;
492 for (
unsigned int i = 0;
i < bench.size();
i++) {
493 PI[
i] = bench[
i].pseudoInverseEigen3();
496 for (
unsigned int i = 0;
i < time.size();
i++) {
497 ret += test_pseudo_inverse(bench, PI);
502 for (
unsigned int i = 0;
i < bench.size();
i++) {
503 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
504 unsigned int rank = bench[
i].pseudoInverseEigen3(PI[i]);
505 if (rank != rank_bench) {
507 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
513 for (
unsigned int i = 0;
i < time.size();
i++) {
514 ret += test_pseudo_inverse(bench, PI);
519 for (
unsigned int i = 0;
i < bench.size();
i++) {
520 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
521 unsigned int rank = bench[
i].pseudoInverseEigen3(PI[i], sv[i]);
522 if (rank != rank_bench) {
524 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
530 for (
unsigned int i = 0;
i < time.size();
i++) {
531 ret += test_pseudo_inverse(bench, PI);
536 for (
unsigned int i = 0;
i < bench.size();
i++) {
537 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
538 unsigned int rank = bench[
i].pseudoInverseEigen3(PI[i], sv[i], 1e-6, imA[i], imAt[i], kerAt[i]);
539 if (rank != rank_bench) {
541 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
547 for (
unsigned int i = 0;
i < time.size();
i++) {
548 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
555 for (
unsigned int i = 0;
i < bench.size();
i++) {
556 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
557 PI[
i] = bench[
i].pseudoInverseEigen3(
static_cast<int>(rank_bench));
560 for (
unsigned int i = 0;
i < time.size();
i++) {
561 ret += test_pseudo_inverse(bench, PI);
566 for (
unsigned int i = 0;
i < bench.size();
i++) {
567 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
568 unsigned int rank = bench[
i].pseudoInverseEigen3(PI[i],
static_cast<int>(rank_bench));
569 if (rank != rank_bench) {
571 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
577 for (
unsigned int i = 0;
i < time.size();
i++) {
578 ret += test_pseudo_inverse(bench, PI);
583 for (
unsigned int i = 0;
i < bench.size();
i++) {
584 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
585 unsigned int rank = bench[
i].pseudoInverseEigen3(PI[i], sv[i],
static_cast<int>(rank_bench));
586 if (rank != rank_bench) {
588 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
594 for (
unsigned int i = 0;
i < time.size();
i++) {
595 ret += test_pseudo_inverse(bench, PI);
600 for (
unsigned int i = 0;
i < bench.size();
i++) {
601 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
602 unsigned int rank = bench[
i].pseudoInverseEigen3(PI[i], sv[i],
static_cast<int>(rank_bench), imA[i], imAt[i], kerAt[i]);
603 if (rank != rank_bench) {
605 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
612 for (
unsigned int i = 0;
i < time.size();
i++) {
613 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
620#if defined(VISP_HAVE_LAPACK)
621int test_pseudo_inverse_lapack(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time)
624 std::cout <<
"Test pseudo-inverse using Eigen3 3rd party" << std::endl;
626 std::cout <<
" Pseudo-inverse on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
628 size_t size = bench.size();
629 std::vector<vpMatrix> PI(size), imA(size), imAt(size), kerAt(size);
630 std::vector<vpColVector> sv(size);
631 int ret = EXIT_SUCCESS;
636 for (
unsigned int i = 0;
i < bench.size();
i++) {
637 PI[
i] = bench[
i].pseudoInverseLapack();
640 for (
unsigned int i = 0;
i < time.size();
i++) {
641 ret += test_pseudo_inverse(bench, PI);
646 for (
unsigned int i = 0;
i < bench.size();
i++) {
647 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
648 unsigned int rank = bench[
i].pseudoInverseLapack(PI[i]);
649 if (rank != rank_bench) {
651 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
657 for (
unsigned int i = 0;
i < time.size();
i++) {
658 ret += test_pseudo_inverse(bench, PI);
663 for (
unsigned int i = 0;
i < bench.size();
i++) {
664 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
665 unsigned int rank = bench[
i].pseudoInverseLapack(PI[i], sv[i]);
666 if (rank != rank_bench) {
668 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
674 for (
unsigned int i = 0;
i < time.size();
i++) {
675 ret += test_pseudo_inverse(bench, PI);
680 for (
unsigned int i = 0;
i < bench.size();
i++) {
681 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
682 unsigned int rank = bench[
i].pseudoInverseLapack(PI[i], sv[i], 1e-6, imA[i], imAt[i], kerAt[i]);
683 if (rank != rank_bench) {
685 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
691 for (
unsigned int i = 0;
i < time.size();
i++) {
692 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
699 for (
unsigned int i = 0;
i < bench.size();
i++) {
700 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
701 PI[
i] = bench[
i].pseudoInverseLapack(
static_cast<int>(rank_bench));
704 for (
unsigned int i = 0;
i < time.size();
i++) {
705 ret += test_pseudo_inverse(bench, PI);
710 for (
unsigned int i = 0;
i < bench.size();
i++) {
711 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
712 unsigned int rank = bench[
i].pseudoInverseLapack(PI[i],
static_cast<int>(rank_bench));
713 if (rank != rank_bench) {
715 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
721 for (
unsigned int i = 0;
i < time.size();
i++) {
722 ret += test_pseudo_inverse(bench, PI);
727 for (
unsigned int i = 0;
i < bench.size();
i++) {
728 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
729 unsigned int rank = bench[
i].pseudoInverseLapack(PI[i], sv[i],
static_cast<int>(rank_bench));
730 if (rank != rank_bench) {
732 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
738 for (
unsigned int i = 0;
i < time.size();
i++) {
739 ret += test_pseudo_inverse(bench, PI);
744 for (
unsigned int i = 0;
i < bench.size();
i++) {
745 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
746 unsigned int rank = bench[
i].pseudoInverseLapack(PI[i], sv[i],
static_cast<int>(rank_bench), imA[i], imAt[i], kerAt[i]);
747 if (rank != rank_bench) {
749 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
756 for (
unsigned int i = 0;
i < time.size();
i++) {
757 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
764#if defined(VISP_HAVE_OPENCV)
765int test_pseudo_inverse_opencv(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time)
768 std::cout <<
"Test pseudo-inverse using OpenCV 3rd party" << std::endl;
770 std::cout <<
" Pseudo-inverse on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
772 size_t size = bench.size();
773 std::vector<vpMatrix> PI(size), imA(size), imAt(size), kerAt(size);
774 std::vector<vpColVector> sv(size);
775 int ret = EXIT_SUCCESS;
780 for (
unsigned int i = 0;
i < bench.size();
i++) {
781 PI[
i] = bench[
i].pseudoInverseOpenCV();
784 for (
unsigned int i = 0;
i < time.size();
i++) {
785 ret += test_pseudo_inverse(bench, PI);
790 for (
unsigned int i = 0;
i < bench.size();
i++) {
791 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
792 unsigned int rank = bench[
i].pseudoInverseOpenCV(PI[i]);
793 if (rank != rank_bench) {
795 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
801 for (
unsigned int i = 0;
i < time.size();
i++) {
802 ret += test_pseudo_inverse(bench, PI);
807 for (
unsigned int i = 0;
i < bench.size();
i++) {
808 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
809 unsigned int rank = bench[
i].pseudoInverseOpenCV(PI[i], sv[i]);
810 if (rank != rank_bench) {
812 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
818 for (
unsigned int i = 0;
i < time.size();
i++) {
819 ret += test_pseudo_inverse(bench, PI);
824 for (
unsigned int i = 0;
i < bench.size();
i++) {
825 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
826 unsigned int rank = bench[
i].pseudoInverseOpenCV(PI[i], sv[i], 1e-6, imA[i], imAt[i], kerAt[i]);
827 if (rank != rank_bench) {
829 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
835 for (
unsigned int i = 0;
i < time.size();
i++) {
836 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
842 for (
unsigned int i = 0;
i < bench.size();
i++) {
843 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
844 PI[
i] = bench[
i].pseudoInverseOpenCV(
static_cast<int>(rank_bench));
847 for (
unsigned int i = 0;
i < time.size();
i++) {
848 ret += test_pseudo_inverse(bench, PI);
853 for (
unsigned int i = 0;
i < bench.size();
i++) {
854 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
855 unsigned int rank = bench[
i].pseudoInverseOpenCV(PI[i],
static_cast<int>(rank_bench));
856 if (rank != rank_bench) {
858 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
864 for (
unsigned int i = 0;
i < time.size();
i++) {
865 ret += test_pseudo_inverse(bench, PI);
870 for (
unsigned int i = 0;
i < bench.size();
i++) {
871 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
872 unsigned int rank = bench[
i].pseudoInverseOpenCV(PI[i], sv[i],
static_cast<int>(rank_bench));
873 if (rank != rank_bench) {
875 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
881 for (
unsigned int i = 0;
i < time.size();
i++) {
882 ret += test_pseudo_inverse(bench, PI);
887 for (
unsigned int i = 0;
i < bench.size();
i++) {
888 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
889 unsigned int rank = bench[
i].pseudoInverseOpenCV(PI[i], sv[i],
static_cast<int>(rank_bench), imA[i], imAt[i], kerAt[i]);
890 if (rank != rank_bench) {
892 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
899 for (
unsigned int i = 0;
i < time.size();
i++) {
900 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
907void save_time(
const std::string &method,
unsigned int nrows,
unsigned int ncols,
bool verbose,
bool use_plot_file,
908 std::ofstream &of,
const std::vector<double> &time)
910 for (
size_t i = 0;
i < time.size();
i++) {
912 of << time[
i] <<
"\t";
914 std::cout <<
" " << method <<
" pseudo inverse (" << nrows <<
"x" << ncols <<
")"
915 <<
" time test " <<
i <<
": " << time[
i] << std::endl;
920int main(
int argc,
const char *argv[])
923#if defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_OPENCV)
924 unsigned int nb_matrices = 10;
925 unsigned int nb_iterations = 10;
926 unsigned int nb_rows = 12;
927 unsigned int nb_cols = 6;
928 bool verbose =
false;
929 std::string plotfile(
"plot-pseudo-inv.csv");
930 bool use_plot_file =
false;
933 unsigned int nb_svd_functions = 4;
934 unsigned int nb_test_matrix_size = 3;
935 std::vector<double> time(nb_svd_functions);
936 std::vector<unsigned int> nrows(nb_test_matrix_size), ncols(nb_test_matrix_size);
939 if (getOptions(argc, argv, nb_matrices, nb_iterations, use_plot_file, plotfile, nb_rows, nb_cols, verbose) ==
944 for (
unsigned int s = 0;
s < nb_test_matrix_size;
s++) {
961 of.open(plotfile.c_str());
965 for (
unsigned int s = 0;
s < nb_test_matrix_size;
s++) {
966 for (
unsigned int i = 0;
i < nb_svd_functions;
i++)
967 of <<
"\"default " << nrows[s] <<
"x" << ncols[s] <<
" test " << i <<
"\""
970#if defined(VISP_HAVE_LAPACK)
971 for (
unsigned int i = 0;
i < nb_svd_functions;
i++)
972 of <<
"\"Lapack " << nrows[s] <<
"x" << ncols[s] <<
" test " << i <<
"\""
975#if defined(VISP_HAVE_EIGEN3)
976 for (
unsigned int i = 0;
i < nb_svd_functions;
i++)
977 of <<
"\"Eigen3 " << nrows[s] <<
"x" << ncols[s] <<
" test " << i <<
"\""
980#if defined(VISP_HAVE_OPENCV)
981 for (
unsigned int i = 0;
i < nb_svd_functions;
i++)
982 of <<
"\"OpenCV " << nrows[s] <<
"x" << ncols[s] <<
" test " << i <<
"\""
989 int ret_default = EXIT_SUCCESS;
990 int ret_lapack = EXIT_SUCCESS;
991 int ret_eigen3 = EXIT_SUCCESS;
992 int ret_opencv = EXIT_SUCCESS;
994 for (
unsigned int iter = 0;
iter < nb_iterations;
iter++) {
999 for (
unsigned int s = 0;
s < nb_test_matrix_size;
s++) {
1000 std::vector<vpMatrix> bench_random_matrices;
1001 create_bench_random_matrix(nb_matrices, nrows[s], ncols[s], verbose, bench_random_matrices);
1003 ret_default += test_pseudo_inverse_default(verbose, bench_random_matrices, time);
1004 save_time(
"default -", nrows[s], ncols[s], verbose, use_plot_file, of, time);
1006#if defined(VISP_HAVE_LAPACK)
1007 ret_lapack += test_pseudo_inverse_lapack(verbose, bench_random_matrices, time);
1008 save_time(
"Lapack -", nrows[s], ncols[s], verbose, use_plot_file, of, time);
1011#if defined(VISP_HAVE_EIGEN3)
1012 ret_eigen3 += test_pseudo_inverse_eigen3(verbose, bench_random_matrices, time);
1013 save_time(
"Eigen3 -", nrows[s], ncols[s], verbose, use_plot_file, of, time);
1016#if defined(VISP_HAVE_OPENCV)
1017 ret_opencv += test_pseudo_inverse_opencv(verbose, bench_random_matrices, time);
1018 save_time(
"OpenCV -", nrows[s], ncols[s], verbose, use_plot_file, of, time);
1024 if (use_plot_file) {
1026 std::cout <<
"Result saved in " << plotfile << std::endl;
1029 std::cout <<
"Resume testing:" << std::endl;
1030 std::cout <<
" Pseudo-inverse (default): " << (ret_default ?
"failed" :
"success") << std::endl;
1031#if defined(VISP_HAVE_LAPACK)
1032 std::cout <<
" Pseudo-inverse (lapack) : " << (ret_lapack ?
"failed" :
"success") << std::endl;
1034#if defined(VISP_HAVE_EIGEN3)
1035 std::cout <<
" Pseudo-inverse (eigen3) : " << (ret_eigen3 ?
"failed" :
"success") << std::endl;
1037#if defined(VISP_HAVE_OPENCV)
1038 std::cout <<
" Pseudo-inverse (opencv) : " << (ret_opencv ?
"failed" :
"success") << std::endl;
1041 int ret = ret_default + ret_lapack + ret_eigen3 + ret_opencv;
1043 std::cout <<
" Global test : " << (ret ?
"failed" :
"success") << std::endl;
1049 std::cout <<
"Test does nothing since you dont't have Lapack, Eigen3 or OpenCV 3rd party" << std::endl;
1050 return EXIT_SUCCESS;
1054 std::cout <<
"Catch an exception: " <<
e.getStringMessage() << std::endl;
1055 return EXIT_FAILURE;
unsigned int getCols() const
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
unsigned int getRows() const
error that can be emitted by ViSP classes.
Implementation of a matrix and operations on matrices.
double frobeniusNorm() const
void insert(const vpMatrix &A, unsigned int r, unsigned int c)
vpMatrix transpose() const
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
VISP_EXPORT double measureTimeMs()