46 #include <visp3/core/vpColVector.h>
47 #include <visp3/core/vpMatrix.h>
48 #include <visp3/core/vpTime.h>
49 #include <visp3/io/vpParseArgv.h>
52 #define GETOPTARGS "cdn:i:pf:R:C:vh"
62 void usage(
const char *name,
const char *badparam)
65 Test matrix pseudo-inverse.\n\
66 Outputs a comparison of the results obtained by supported 3rd parties.\n\
69 %s [-n <number of matrices>] [-f <plot filename>]\n\
70 [-R <number of rows>] [-C <number of columns>]\n\
71 [-i <number of iterations>] [-p] [-h]\n",
76 -n <number of matrices> \n\
77 Number of matrices inverted during each test loop.\n\
79 -i <number of iterations> \n\
80 Number of iterations of the test.\n\
82 -f <plot filename> \n\
83 Set output path for plot output.\n\
84 The plot logs the times of \n\
85 the different inversion methods: \n\
86 QR,LU,Cholesky and Pseudo-inverse.\n\
88 -R <number of rows>\n\
89 Number of rows of the automatically generated matrices \n\
92 -C <number of columns>\n\
93 Number of colums of the automatically generated matrices \n\
97 Plot into filename in the gnuplot format. \n\
98 If this option is used, tests results will be logged \n\
99 into a filename specified with -f.\n\
102 Print the help.\n\n");
105 fprintf(stderr,
"ERROR: \n");
106 fprintf(stderr,
"\nBad parameter [%s]\n", badparam);
117 bool getOptions(
int argc,
const char **argv,
unsigned int &nb_matrices,
unsigned int &nb_iterations,
118 bool &use_plot_file, std::string &plotfile,
unsigned int &nbrows,
unsigned int &nbcols,
bool &verbose)
126 usage(argv[0],
nullptr);
130 nb_matrices = (
unsigned int)atoi(optarg_);
133 nb_iterations = (
unsigned int)atoi(optarg_);
137 use_plot_file =
true;
140 use_plot_file =
true;
143 nbrows = (
unsigned int)atoi(optarg_);
146 nbcols = (
unsigned int)atoi(optarg_);
157 usage(argv[0], optarg_);
163 if ((c == 1) || (c == -1)) {
165 usage(argv[0],
nullptr);
166 std::cerr <<
"ERROR: " << std::endl;
167 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
174 vpMatrix make_random_matrix(
unsigned int nbrows,
unsigned int nbcols)
179 for (
unsigned int i = 0; i < A.
getRows(); i++) {
180 for (
unsigned int j = 0; j < A.
getCols(); j++) {
181 A[i][j] = (double)rand() / (double)RAND_MAX;
188 void create_bench_random_matrix(
unsigned int nb_matrices,
unsigned int nb_rows,
unsigned int nb_cols,
bool verbose,
189 std::vector<vpMatrix> &bench)
192 std::cout <<
"Create a bench of " << nb_matrices <<
" " << nb_rows <<
" by " << nb_cols <<
" matrices" << std::endl;
194 for (
unsigned int i = 0; i < nb_matrices; i++) {
195 vpMatrix M = make_random_matrix(nb_rows, nb_cols);
200 int test_pseudo_inverse(
const std::vector<vpMatrix> &A,
const std::vector<vpMatrix> &Api)
202 double allowed_error = 1e-3;
206 for (
unsigned int i = 0; i < A.size(); i++) {
207 error = (A[i] * Api[i] * A[i] - A[i]).frobeniusNorm();
208 if (error > allowed_error) {
209 std::cout <<
"Bad pseudo-inverse [" << i <<
"] test A A^+ A = A: euclidean norm: " << error << std::endl;
212 error = (Api[i] * A[i] * Api[i] - Api[i]).frobeniusNorm();
213 if (error > allowed_error) {
214 std::cout <<
"Bad pseudo-inverse [" << i <<
"] test A^+ A A^+ = A^+: euclidean norm: " << error << std::endl;
217 A_Api = A[i] * Api[i];
218 error = (A_Api.
transpose() - A_Api).frobeniusNorm();
219 if (error > allowed_error) {
220 std::cout <<
"Bad pseudo-inverse [" << i <<
"] test (A A^+)^T = A A^+: euclidean norm: " << error << std::endl;
223 Api_A = Api[i] * A[i];
224 error = (Api_A.
transpose() - Api_A).frobeniusNorm();
225 if (error > allowed_error) {
226 std::cout <<
"Bad pseudo-inverse [" << i <<
"] test (A^+ A )^T = A^+ A: euclidean norm: " << error << std::endl;
234 int test_pseudo_inverse(
const std::vector<vpMatrix> &A,
const std::vector<vpMatrix> &Api,
235 const std::vector<vpColVector> &sv,
const std::vector<vpMatrix> &imA,
236 const std::vector<vpMatrix> &imAt,
const std::vector<vpMatrix> &kerAt)
238 double allowed_error = 1e-3;
240 if (test_pseudo_inverse(A, Api) == EXIT_FAILURE) {
245 for (
unsigned int i = 0; i < kerAt.size(); i++) {
246 if (kerAt[i].size()) {
247 vpMatrix nullspace = A[i] * kerAt[i].
t();
249 if (error > allowed_error) {
250 std::cout <<
"Bad kernel [" << i <<
"]: euclidean norm: " << error << std::endl;
257 for (
unsigned int i = 0; i < kerAt.size(); i++) {
258 unsigned int rank = imA[i].getCols();
259 vpMatrix U, S(rank, A[i].getCols()), Vt(A[i].getCols(), A[i].getCols());
262 for (
unsigned int j = 0; j < rank; j++)
265 Vt.
insert(imAt[i].t(), 0, 0);
266 Vt.insert(kerAt[i], imAt[i].getCols(), 0);
268 double error = (U * S * Vt - A[i]).frobeniusNorm();
270 if (error > allowed_error) {
271 std::cout <<
"Bad imA, imAt, sv, kerAt [" << i <<
"]: euclidean norm: " << error << std::endl;
279 int test_pseudo_inverse_default(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time)
282 std::cout <<
"Test pseudo-inverse using default 3rd party" << std::endl;
284 std::cout <<
" Pseudo-inverse on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
286 size_t size = bench.size();
287 std::vector<vpMatrix> PI(size), imA(size), imAt(size), kerAt(size);
288 std::vector<vpColVector> sv(size);
289 int ret = EXIT_SUCCESS;
294 for (
unsigned int i = 0; i < bench.size(); i++) {
295 PI[i] = bench[i].pseudoInverse();
298 for (
unsigned int i = 0; i < time.size(); i++) {
299 ret += test_pseudo_inverse(bench, PI);
304 for (
unsigned int i = 0; i < bench.size(); i++) {
305 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
306 unsigned int rank = bench[i].pseudoInverse(PI[i]);
307 if (rank != rank_bench) {
309 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
315 for (
unsigned int i = 0; i < time.size(); i++) {
316 ret += test_pseudo_inverse(bench, PI);
321 for (
unsigned int i = 0; i < bench.size(); i++) {
322 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
323 unsigned int rank = bench[i].pseudoInverse(PI[i], sv[i]);
324 if (rank != rank_bench) {
326 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
332 for (
unsigned int i = 0; i < time.size(); i++) {
333 ret += test_pseudo_inverse(bench, PI);
338 for (
unsigned int i = 0; i < bench.size(); i++) {
339 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
340 unsigned int rank = bench[i].pseudoInverse(PI[i], sv[i], 1e-6, imA[i], imAt[i]);
341 if (rank != rank_bench) {
343 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
349 for (
unsigned int i = 0; i < time.size(); i++) {
350 ret += test_pseudo_inverse(bench, PI);
355 for (
unsigned int i = 0; i < bench.size(); i++) {
356 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
357 unsigned int rank = bench[i].pseudoInverse(PI[i], sv[i], 1e-6, imA[i], imAt[i], kerAt[i]);
358 if (rank != rank_bench) {
360 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
366 for (
unsigned int i = 0; i < time.size(); i++) {
367 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
374 for (
unsigned int i = 0; i < bench.size(); i++) {
375 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
376 PI[i] = bench[i].pseudoInverse(
static_cast<int>(rank_bench));
379 for (
unsigned int i = 0; i < time.size(); i++) {
380 ret += test_pseudo_inverse(bench, PI);
385 for (
unsigned int i = 0; i < bench.size(); i++) {
386 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
387 unsigned int rank = bench[i].pseudoInverse(PI[i],
static_cast<int>(rank_bench));
388 if (rank != rank_bench) {
390 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
396 for (
unsigned int i = 0; i < time.size(); i++) {
397 ret += test_pseudo_inverse(bench, PI);
402 for (
unsigned int i = 0; i < bench.size(); i++) {
403 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
404 unsigned int rank = bench[i].pseudoInverse(PI[i], sv[i],
static_cast<int>(rank_bench));
405 if (rank != rank_bench) {
407 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
413 for (
unsigned int i = 0; i < time.size(); i++) {
414 ret += test_pseudo_inverse(bench, PI);
419 for (
unsigned int i = 0; i < bench.size(); i++) {
420 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
421 unsigned int rank = bench[i].pseudoInverse(PI[i], sv[i],
static_cast<int>(rank_bench), imA[i], imAt[i]);
422 if (rank != rank_bench) {
424 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
430 for (
unsigned int i = 0; i < time.size(); i++) {
431 ret += test_pseudo_inverse(bench, PI);
436 for (
unsigned int i = 0; i < bench.size(); i++) {
437 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
438 unsigned int rank = bench[i].pseudoInverse(PI[i], sv[i],
static_cast<int>(rank_bench), imA[i], imAt[i], kerAt[i]);
439 if (rank != rank_bench) {
441 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
447 for (
unsigned int i = 0; i < time.size(); i++) {
448 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
454 #if defined(VISP_HAVE_EIGEN3)
455 int test_pseudo_inverse_eigen3(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time)
458 std::cout <<
"Test pseudo-inverse using Eigen3 3rd party" << std::endl;
460 std::cout <<
" Pseudo-inverse on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
462 size_t size = bench.size();
463 std::vector<vpMatrix> PI(size), imA(size), imAt(size), kerAt(size);
464 std::vector<vpColVector> sv(size);
465 int ret = EXIT_SUCCESS;
470 for (
unsigned int i = 0; i < bench.size(); i++) {
471 PI[i] = bench[i].pseudoInverseEigen3();
474 for (
unsigned int i = 0; i < time.size(); i++) {
475 ret += test_pseudo_inverse(bench, PI);
480 for (
unsigned int i = 0; i < bench.size(); i++) {
481 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
482 unsigned int rank = bench[i].pseudoInverseEigen3(PI[i]);
483 if (rank != rank_bench) {
485 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
491 for (
unsigned int i = 0; i < time.size(); i++) {
492 ret += test_pseudo_inverse(bench, PI);
497 for (
unsigned int i = 0; i < bench.size(); i++) {
498 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
499 unsigned int rank = bench[i].pseudoInverseEigen3(PI[i], sv[i]);
500 if (rank != rank_bench) {
502 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
508 for (
unsigned int i = 0; i < time.size(); i++) {
509 ret += test_pseudo_inverse(bench, PI);
514 for (
unsigned int i = 0; i < bench.size(); i++) {
515 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
516 unsigned int rank = bench[i].pseudoInverseEigen3(PI[i], sv[i], 1e-6, imA[i], imAt[i], kerAt[i]);
517 if (rank != rank_bench) {
519 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
525 for (
unsigned int i = 0; i < time.size(); i++) {
526 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
533 for (
unsigned int i = 0; i < bench.size(); i++) {
534 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
535 PI[i] = bench[i].pseudoInverseEigen3(
static_cast<int>(rank_bench));
538 for (
unsigned int i = 0; i < time.size(); i++) {
539 ret += test_pseudo_inverse(bench, PI);
544 for (
unsigned int i = 0; i < bench.size(); i++) {
545 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
546 unsigned int rank = bench[i].pseudoInverseEigen3(PI[i],
static_cast<int>(rank_bench));
547 if (rank != rank_bench) {
549 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
555 for (
unsigned int i = 0; i < time.size(); i++) {
556 ret += test_pseudo_inverse(bench, PI);
561 for (
unsigned int i = 0; i < bench.size(); i++) {
562 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
563 unsigned int rank = bench[i].pseudoInverseEigen3(PI[i], sv[i],
static_cast<int>(rank_bench));
564 if (rank != rank_bench) {
566 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
572 for (
unsigned int i = 0; i < time.size(); i++) {
573 ret += test_pseudo_inverse(bench, PI);
578 for (
unsigned int i = 0; i < bench.size(); i++) {
579 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
580 unsigned int rank = bench[i].pseudoInverseEigen3(PI[i], sv[i],
static_cast<int>(rank_bench), imA[i], imAt[i], kerAt[i]);
581 if (rank != rank_bench) {
583 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
590 for (
unsigned int i = 0; i < time.size(); i++) {
591 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
598 #if defined(VISP_HAVE_LAPACK)
599 int test_pseudo_inverse_lapack(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time)
602 std::cout <<
"Test pseudo-inverse using Eigen3 3rd party" << std::endl;
604 std::cout <<
" Pseudo-inverse on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
606 size_t size = bench.size();
607 std::vector<vpMatrix> PI(size), imA(size), imAt(size), kerAt(size);
608 std::vector<vpColVector> sv(size);
609 int ret = EXIT_SUCCESS;
614 for (
unsigned int i = 0; i < bench.size(); i++) {
615 PI[i] = bench[i].pseudoInverseLapack();
618 for (
unsigned int i = 0; i < time.size(); i++) {
619 ret += test_pseudo_inverse(bench, PI);
624 for (
unsigned int i = 0; i < bench.size(); i++) {
625 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
626 unsigned int rank = bench[i].pseudoInverseLapack(PI[i]);
627 if (rank != rank_bench) {
629 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
635 for (
unsigned int i = 0; i < time.size(); i++) {
636 ret += test_pseudo_inverse(bench, PI);
641 for (
unsigned int i = 0; i < bench.size(); i++) {
642 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
643 unsigned int rank = bench[i].pseudoInverseLapack(PI[i], sv[i]);
644 if (rank != rank_bench) {
646 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
652 for (
unsigned int i = 0; i < time.size(); i++) {
653 ret += test_pseudo_inverse(bench, PI);
658 for (
unsigned int i = 0; i < bench.size(); i++) {
659 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
660 unsigned int rank = bench[i].pseudoInverseLapack(PI[i], sv[i], 1e-6, imA[i], imAt[i], kerAt[i]);
661 if (rank != rank_bench) {
663 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
669 for (
unsigned int i = 0; i < time.size(); i++) {
670 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
677 for (
unsigned int i = 0; i < bench.size(); i++) {
678 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
679 PI[i] = bench[i].pseudoInverseLapack(
static_cast<int>(rank_bench));
682 for (
unsigned int i = 0; i < time.size(); i++) {
683 ret += test_pseudo_inverse(bench, PI);
688 for (
unsigned int i = 0; i < bench.size(); i++) {
689 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
690 unsigned int rank = bench[i].pseudoInverseLapack(PI[i],
static_cast<int>(rank_bench));
691 if (rank != rank_bench) {
693 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
699 for (
unsigned int i = 0; i < time.size(); i++) {
700 ret += test_pseudo_inverse(bench, PI);
705 for (
unsigned int i = 0; i < bench.size(); i++) {
706 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
707 unsigned int rank = bench[i].pseudoInverseLapack(PI[i], sv[i],
static_cast<int>(rank_bench));
708 if (rank != rank_bench) {
710 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
716 for (
unsigned int i = 0; i < time.size(); i++) {
717 ret += test_pseudo_inverse(bench, PI);
722 for (
unsigned int i = 0; i < bench.size(); i++) {
723 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
724 unsigned int rank = bench[i].pseudoInverseLapack(PI[i], sv[i],
static_cast<int>(rank_bench), imA[i], imAt[i], kerAt[i]);
725 if (rank != rank_bench) {
727 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
734 for (
unsigned int i = 0; i < time.size(); i++) {
735 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
742 #if defined(VISP_HAVE_OPENCV)
743 int test_pseudo_inverse_opencv(
bool verbose,
const std::vector<vpMatrix> &bench, std::vector<double> &time)
746 std::cout <<
"Test pseudo-inverse using OpenCV 3rd party" << std::endl;
748 std::cout <<
" Pseudo-inverse on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
750 size_t size = bench.size();
751 std::vector<vpMatrix> PI(size), imA(size), imAt(size), kerAt(size);
752 std::vector<vpColVector> sv(size);
753 int ret = EXIT_SUCCESS;
758 for (
unsigned int i = 0; i < bench.size(); i++) {
759 PI[i] = bench[i].pseudoInverseOpenCV();
762 for (
unsigned int i = 0; i < time.size(); i++) {
763 ret += test_pseudo_inverse(bench, PI);
768 for (
unsigned int i = 0; i < bench.size(); i++) {
769 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
770 unsigned int rank = bench[i].pseudoInverseOpenCV(PI[i]);
771 if (rank != rank_bench) {
773 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
779 for (
unsigned int i = 0; i < time.size(); i++) {
780 ret += test_pseudo_inverse(bench, PI);
785 for (
unsigned int i = 0; i < bench.size(); i++) {
786 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
787 unsigned int rank = bench[i].pseudoInverseOpenCV(PI[i], sv[i]);
788 if (rank != rank_bench) {
790 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
796 for (
unsigned int i = 0; i < time.size(); i++) {
797 ret += test_pseudo_inverse(bench, PI);
802 for (
unsigned int i = 0; i < bench.size(); i++) {
803 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
804 unsigned int rank = bench[i].pseudoInverseOpenCV(PI[i], sv[i], 1e-6, imA[i], imAt[i], kerAt[i]);
805 if (rank != rank_bench) {
807 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
813 for (
unsigned int i = 0; i < time.size(); i++) {
814 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
820 for (
unsigned int i = 0; i < bench.size(); i++) {
821 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
822 PI[i] = bench[i].pseudoInverseOpenCV(
static_cast<int>(rank_bench));
825 for (
unsigned int i = 0; i < time.size(); i++) {
826 ret += test_pseudo_inverse(bench, PI);
831 for (
unsigned int i = 0; i < bench.size(); i++) {
832 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
833 unsigned int rank = bench[i].pseudoInverseOpenCV(PI[i],
static_cast<int>(rank_bench));
834 if (rank != rank_bench) {
836 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
842 for (
unsigned int i = 0; i < time.size(); i++) {
843 ret += test_pseudo_inverse(bench, PI);
848 for (
unsigned int i = 0; i < bench.size(); i++) {
849 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
850 unsigned int rank = bench[i].pseudoInverseOpenCV(PI[i], sv[i],
static_cast<int>(rank_bench));
851 if (rank != rank_bench) {
853 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
859 for (
unsigned int i = 0; i < time.size(); i++) {
860 ret += test_pseudo_inverse(bench, PI);
865 for (
unsigned int i = 0; i < bench.size(); i++) {
866 unsigned int rank_bench = std::min(bench[i].getRows(), bench[i].getCols());
867 unsigned int rank = bench[i].pseudoInverseOpenCV(PI[i], sv[i],
static_cast<int>(rank_bench), imA[i], imAt[i], kerAt[i]);
868 if (rank != rank_bench) {
870 std::cout <<
" Error in the rank (" << rank <<
")" <<
" while expected rank is " << rank_bench << std::endl;
877 for (
unsigned int i = 0; i < time.size(); i++) {
878 ret += test_pseudo_inverse(bench, PI, sv, imA, imAt, kerAt);
885 void save_time(
const std::string &method,
unsigned int nrows,
unsigned int ncols,
bool verbose,
bool use_plot_file,
886 std::ofstream &of,
const std::vector<double> &time)
888 for (
size_t i = 0; i < time.size(); i++) {
890 of << time[i] <<
"\t";
892 std::cout <<
" " << method <<
" pseudo inverse (" << nrows <<
"x" << ncols <<
")"
893 <<
" time test " << i <<
": " << time[i] << std::endl;
898 int main(
int argc,
const char *argv[])
901 #if defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_OPENCV)
902 unsigned int nb_matrices = 10;
903 unsigned int nb_iterations = 10;
904 unsigned int nb_rows = 12;
905 unsigned int nb_cols = 6;
906 bool verbose =
false;
907 std::string plotfile(
"plot-pseudo-inv.csv");
908 bool use_plot_file =
false;
911 unsigned int nb_svd_functions = 4;
912 unsigned int nb_test_matrix_size = 3;
913 std::vector<double> time(nb_svd_functions);
914 std::vector<unsigned int> nrows(nb_test_matrix_size), ncols(nb_test_matrix_size);
917 if (getOptions(argc, argv, nb_matrices, nb_iterations, use_plot_file, plotfile, nb_rows, nb_cols, verbose) ==
922 for (
unsigned int s = 0; s < nb_test_matrix_size; s++) {
939 of.open(plotfile.c_str());
943 for (
unsigned int s = 0; s < nb_test_matrix_size; s++) {
944 for (
unsigned int i = 0; i < nb_svd_functions; i++)
945 of <<
"\"default " << nrows[s] <<
"x" << ncols[s] <<
" test " << i <<
"\""
948 #if defined(VISP_HAVE_LAPACK)
949 for (
unsigned int i = 0; i < nb_svd_functions; i++)
950 of <<
"\"Lapack " << nrows[s] <<
"x" << ncols[s] <<
" test " << i <<
"\""
953 #if defined(VISP_HAVE_EIGEN3)
954 for (
unsigned int i = 0; i < nb_svd_functions; i++)
955 of <<
"\"Eigen3 " << nrows[s] <<
"x" << ncols[s] <<
" test " << i <<
"\""
958 #if defined(VISP_HAVE_OPENCV)
959 for (
unsigned int i = 0; i < nb_svd_functions; i++)
960 of <<
"\"OpenCV " << nrows[s] <<
"x" << ncols[s] <<
" test " << i <<
"\""
967 int ret_default = EXIT_SUCCESS;
968 int ret_lapack = EXIT_SUCCESS;
969 int ret_eigen3 = EXIT_SUCCESS;
970 int ret_opencv = EXIT_SUCCESS;
972 for (
unsigned int iter = 0; iter < nb_iterations; iter++) {
977 for (
unsigned int s = 0; s < nb_test_matrix_size; s++) {
978 std::vector<vpMatrix> bench_random_matrices;
979 create_bench_random_matrix(nb_matrices, nrows[s], ncols[s], verbose, bench_random_matrices);
981 ret_default += test_pseudo_inverse_default(verbose, bench_random_matrices, time);
982 save_time(
"default -", nrows[s], ncols[s], verbose, use_plot_file, of, time);
984 #if defined(VISP_HAVE_LAPACK)
985 ret_lapack += test_pseudo_inverse_lapack(verbose, bench_random_matrices, time);
986 save_time(
"Lapack -", nrows[s], ncols[s], verbose, use_plot_file, of, time);
989 #if defined(VISP_HAVE_EIGEN3)
990 ret_eigen3 += test_pseudo_inverse_eigen3(verbose, bench_random_matrices, time);
991 save_time(
"Eigen3 -", nrows[s], ncols[s], verbose, use_plot_file, of, time);
994 #if defined(VISP_HAVE_OPENCV)
995 ret_opencv += test_pseudo_inverse_opencv(verbose, bench_random_matrices, time);
996 save_time(
"OpenCV -", nrows[s], ncols[s], verbose, use_plot_file, of, time);
1002 if (use_plot_file) {
1004 std::cout <<
"Result saved in " << plotfile << std::endl;
1007 std::cout <<
"Resume testing:" << std::endl;
1008 std::cout <<
" Pseudo-inverse (default): " << (ret_default ?
"failed" :
"success") << std::endl;
1009 #if defined(VISP_HAVE_LAPACK)
1010 std::cout <<
" Pseudo-inverse (lapack) : " << (ret_lapack ?
"failed" :
"success") << std::endl;
1012 #if defined(VISP_HAVE_EIGEN3)
1013 std::cout <<
" Pseudo-inverse (eigen3) : " << (ret_eigen3 ?
"failed" :
"success") << std::endl;
1015 #if defined(VISP_HAVE_OPENCV)
1016 std::cout <<
" Pseudo-inverse (opencv) : " << (ret_opencv ?
"failed" :
"success") << std::endl;
1019 int ret = ret_default + ret_lapack + ret_eigen3 + ret_opencv;
1021 std::cout <<
" Global test : " << (ret ?
"failed" :
"success") << std::endl;
1027 std::cout <<
"Test does nothing since you dont't have Lapack, Eigen3 or OpenCV 3rd party" << std::endl;
1028 return EXIT_SUCCESS;
1033 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.
const std::string & getStringMessage() const
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()