50 #include <visp3/core/vpColVector.h> 51 #include <visp3/core/vpMatrix.h> 52 #include <visp3/core/vpTime.h> 53 #include <visp3/io/vpParseArgv.h> 56 #define GETOPTARGS "cdn:i:pf:R:C:vh" 66 void usage(
const char *name,
const char *badparam)
69 Test matrix inversions\n\ 70 using LU, QR and Cholesky methods as well as Pseudo-inverse.\n\ 71 Outputs a comparison of these methods.\n\ 74 %s [-n <number of matrices>] [-f <plot filename>]\n\ 75 [-R <number of rows>] [-C <number of columns>]\n\ 76 [-i <number of iterations>] [-p] [-h]\n", name);
80 -n <number of matrices> \n\ 81 Number of matrices inverted during each test loop.\n\ 83 -i <number of iterations> \n\ 84 Number of iterations of the test.\n\ 86 -f <plot filename> \n\ 87 Set output path for plot output.\n\ 88 The plot logs the times of \n\ 89 the different inversion methods: \n\ 90 QR,LU,Cholesky and Pseudo-inverse.\n\ 92 -R <number of rows>\n\ 93 Number of rows of the automatically generated matrices \n\ 96 -C <number of columns>\n\ 97 Number of colums of the automatically generated matrices \n\ 101 Plot into filename in the gnuplot format. \n\ 102 If this option is used, tests results will be logged \n\ 103 into a filename specified with -f.\n\ 106 Print the help.\n\n");
109 fprintf(stderr,
"ERROR: \n");
110 fprintf(stderr,
"\nBad parameter [%s]\n", badparam);
121 bool getOptions(
int argc,
const char **argv,
unsigned int &nb_matrices,
unsigned int &nb_iterations,
122 bool &use_plot_file, std::string &plotfile,
unsigned int &nbrows,
unsigned int &nbcols,
bool &verbose)
130 usage(argv[0], NULL);
134 nb_matrices = (
unsigned int)atoi(optarg_);
137 nb_iterations = (
unsigned int)atoi(optarg_);
141 use_plot_file =
true;
144 use_plot_file =
true;
147 nbrows = (
unsigned int)atoi(optarg_);
150 nbcols = (
unsigned int)atoi(optarg_);
161 usage(argv[0], optarg_);
167 if ((c == 1) || (c == -1)) {
169 usage(argv[0], NULL);
170 std::cerr <<
"ERROR: " << std::endl;
171 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
178 vpMatrix make_random_matrix(
unsigned int nbrows,
unsigned int nbcols)
183 for (
unsigned int i = 0; i < A.
getRows(); i++) {
184 for (
unsigned int j = 0; j < A.
getCols(); j++) {
185 A[i][j] =
static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
192 vpMatrix make_random_symmetric_matrix(
unsigned int nbrows)
197 for(
unsigned int i=0; i < A.
getRows(); i++) {
198 for(
unsigned int j=i; j<A.
getCols(); j++) {
199 A[i][j] =
static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
209 void create_bench_random_matrix(
unsigned int nb_matrices,
unsigned int nb_rows,
unsigned int nb_cols,
bool verbose,
210 std::vector<vpMatrix> &bench)
213 std::cout <<
"Create a bench of " << nb_matrices <<
" " << nb_rows <<
" by " << nb_cols <<
" matrices" << std::endl;
215 for (
unsigned int i = 0; i < nb_matrices; i++) {
231 M = make_random_matrix(nb_rows, nb_cols);
237 void create_bench_random_symmetric_matrix(
unsigned int nb_matrices,
unsigned int nb_rows,
bool verbose,
238 std::vector<vpMatrix> &bench)
241 std::cout <<
"Create a bench of " << nb_matrices <<
" " << nb_rows <<
" by " << nb_rows <<
" symmetric matrices" << std::endl;
243 for (
unsigned int i = 0; i < nb_matrices; i++) {
259 M = make_random_symmetric_matrix(nb_rows);
265 int test_svd(std::vector<vpMatrix> M, std::vector<vpMatrix> U, std::vector<vpColVector> s, std::vector<vpMatrix> V)
267 for (
unsigned int i = 0; i < M.size(); i++) {
273 std::cout <<
"SVD decomposition failed" << std::endl;
280 int test_eigen_values(std::vector<vpMatrix> M, std::vector<vpColVector> e, std::vector<vpMatrix> V, std::vector<vpColVector> e2)
282 for (
unsigned int i = 0; i < M.size(); i++) {
285 std::cout <<
"Eigen values differ" << std::endl;
290 vpMatrix MV_VD = M[i] * V[i] - V[i] * D;
292 std::cout <<
"Eigen values/vector decomposition failed" << std::endl;
299 #if defined(VISP_HAVE_EIGEN3) 300 int test_svd_eigen3(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time)
303 std::cout <<
"Test SVD using Eigen3 3rd party" << std::endl;
306 std::cout <<
" SVD on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
308 std::vector<vpMatrix> U = bench;
309 std::vector<vpMatrix> V(bench.size());
310 std::vector<vpColVector> s(bench.size());
313 for (
unsigned int i = 0; i < bench.size(); i++) {
314 U[i].svdEigen3(s[i], V[i]);
319 return test_svd(bench, U, s, V);
323 #if defined(VISP_HAVE_LAPACK) 324 int test_svd_lapack(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time)
327 std::cout <<
"Test SVD using Lapack 3rd party" << std::endl;
330 std::cout <<
" SVD on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
332 std::vector<vpMatrix> U = bench;
333 std::vector<vpMatrix> V(bench.size());
334 std::vector<vpColVector> s(bench.size());
337 for (
unsigned int i = 0; i < bench.size(); i++) {
338 U[i].svdLapack(s[i], V[i]);
342 return test_svd(bench, U, s, V);
345 int test_eigen_values_lapack(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time)
348 std::cout <<
"Test eigenValues() using Lapack 3rd party" << std::endl;
350 std::vector<vpColVector> e(bench.size());
351 std::vector<vpColVector> e2(bench.size());
352 std::vector<vpMatrix> V(bench.size());
354 for (
unsigned int i = 0; i < bench.size(); i++) {
355 e2[i] = bench[i].eigenValues();
360 for (
unsigned int i = 0; i < bench.size(); i++) {
361 bench[i].eigenValues(e[i], V[i]);
365 return test_eigen_values(bench, e, V, e2);
369 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101) 370 int test_svd_opencv(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time)
373 std::cout <<
"Test SVD using OpenCV 3rd party" << std::endl;
376 std::cout <<
" SVD on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
378 std::vector<vpMatrix> U = bench;
379 std::vector<vpMatrix> V(bench.size());
380 std::vector<vpColVector> s(bench.size());
383 for (
unsigned int i = 0; i < bench.size(); i++) {
384 U[i].svdOpenCV(s[i], V[i]);
388 return test_svd(bench, U, s, V);
392 void save_time(
const std::string &method,
bool verbose,
bool use_plot_file, std::ofstream &of,
double time)
396 if (verbose || !use_plot_file) {
397 std::cout << method << time << std::endl;
401 int main(
int argc,
const char *argv[])
404 #if defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_LAPACK) || (VISP_HAVE_OPENCV_VERSION >= 0x020101) 405 unsigned int nb_matrices = 100;
406 unsigned int nb_iterations = 10;
407 unsigned int nb_rows = 6;
408 unsigned int nb_cols = 6;
409 unsigned int nb_rows_sym = 5;
410 bool verbose =
false;
411 std::string plotfile(
"plot-svd.csv");
412 bool use_plot_file =
false;
416 if (getOptions(argc, argv, nb_matrices, nb_iterations, use_plot_file, plotfile, nb_rows, nb_cols, verbose) ==
422 of.open(plotfile.c_str());
426 #if defined(VISP_HAVE_LAPACK) 427 of <<
"\"SVD Lapack\"" 430 #if defined(VISP_HAVE_EIGEN3) 431 of <<
"\"SVD Eigen3\"" 434 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101) 435 of <<
"\"SVD OpenCV\"" 441 int ret = EXIT_SUCCESS;
442 for (
unsigned int iter = 0; iter < nb_iterations; iter++) {
443 std::vector<vpMatrix> bench_random_matrices;
444 create_bench_random_matrix(nb_matrices, nb_rows, nb_cols, verbose, bench_random_matrices);
445 std::vector<vpMatrix> bench_random_symmetric_matrices;
446 create_bench_random_symmetric_matrix(nb_matrices, nb_rows_sym, verbose, bench_random_symmetric_matrices);
452 #if defined(VISP_HAVE_LAPACK) 453 ret += test_svd_lapack(verbose, bench_random_matrices, time);
454 save_time(
"SVD (Lapack): ", verbose, use_plot_file, of, time);
457 #if defined(VISP_HAVE_EIGEN3) 458 ret += test_svd_eigen3(verbose, bench_random_matrices, time);
459 save_time(
"SVD (Eigen3): ", verbose, use_plot_file, of, time);
462 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101) 463 ret += test_svd_opencv(verbose, bench_random_matrices, time);
464 save_time(
"SVD (OpenCV): ", verbose, use_plot_file, of, time);
467 #if defined(VISP_HAVE_LAPACK) 468 ret += test_eigen_values_lapack(verbose, bench_random_symmetric_matrices, time);
469 save_time(
"Eigen values (Lapack): ", verbose, use_plot_file, of, time);
477 std::cout <<
"Result saved in " << plotfile << std::endl;
480 if (ret == EXIT_SUCCESS) {
481 std::cout <<
"Test succeed" << std::endl;
483 std::cout <<
"Test failed" << std::endl;
490 std::cout <<
"Test does nothing since you dont't have Lapack, Eigen3 or OpenCV 3rd party" Implementation of a matrix and operations on matrices.
double frobeniusNorm() const
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
error that can be emited by ViSP classes.
unsigned int getCols() const
VISP_EXPORT double measureTimeMs()
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
double frobeniusNorm() const
void diag(const double &val=1.0)
unsigned int getRows() const
Implementation of column vector and the associated operations.
const std::string & getStringMessage() const
Send a reference (constant) related the error message (can be empty).