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] = (double)rand() / (double)RAND_MAX;
192 void create_bench_random_matrix(
unsigned int nb_matrices,
unsigned int nb_rows,
unsigned int nb_cols,
bool verbose,
193 std::vector<vpMatrix> &bench)
196 std::cout <<
"Create a bench of " << nb_matrices <<
" " << nb_rows <<
" by " << nb_cols <<
" matrices" << std::endl;
198 for (
unsigned int i = 0; i < nb_matrices; i++) {
214 M = make_random_matrix(nb_rows, nb_cols);
220 int test_svd(std::vector<vpMatrix> M, std::vector<vpMatrix> U, std::vector<vpColVector> s, std::vector<vpMatrix> V)
222 for (
unsigned int i = 0; i < M.size(); i++) {
228 std::cout <<
"SVD decomposition failed" << std::endl;
235 #if defined(VISP_HAVE_EIGEN3) 236 int test_svd_eigen3(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time)
239 std::cout <<
"Test SVD using Eigen3 3rd party" << std::endl;
242 std::cout <<
" SVD on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
244 std::vector<vpMatrix> U = bench;
245 std::vector<vpMatrix> V(bench.size());
246 std::vector<vpColVector> s(bench.size());
249 for (
unsigned int i = 0; i < bench.size(); i++) {
250 U[i].svdEigen3(s[i], V[i]);
255 return test_svd(bench, U, s, V);
259 #if defined(VISP_HAVE_LAPACK) 260 int test_svd_lapack(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time)
263 std::cout <<
"Test SVD using Lapack 3rd party" << std::endl;
266 std::cout <<
" SVD on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
268 std::vector<vpMatrix> U = bench;
269 std::vector<vpMatrix> V(bench.size());
270 std::vector<vpColVector> s(bench.size());
273 for (
unsigned int i = 0; i < bench.size(); i++) {
274 U[i].svdLapack(s[i], V[i]);
278 return test_svd(bench, U, s, V);
282 #if defined(VISP_HAVE_GSL) 283 int test_svd_gsl(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time)
286 std::cout <<
"Test SVD using GSL 3rd party" << std::endl;
289 std::cout <<
" SVD on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
291 std::vector<vpMatrix> U = bench;
292 std::vector<vpMatrix> V(bench.size());
293 std::vector<vpColVector> s(bench.size());
296 for (
unsigned int i = 0; i < bench.size(); i++) {
297 U[i].svdGsl(s[i], V[i]);
302 return test_svd(bench, U, s, V);
306 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101) 307 int test_svd_opencv(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time)
310 std::cout <<
"Test SVD using OpenCV 3rd party" << std::endl;
313 std::cout <<
" SVD on a " << bench[0].getRows() <<
"x" << bench[0].getCols() <<
" matrix" << std::endl;
315 std::vector<vpMatrix> U = bench;
316 std::vector<vpMatrix> V(bench.size());
317 std::vector<vpColVector> s(bench.size());
320 for (
unsigned int i = 0; i < bench.size(); i++) {
321 U[i].svdOpenCV(s[i], V[i]);
325 return test_svd(bench, U, s, V);
329 void save_time(
const std::string &method,
bool verbose,
bool use_plot_file, std::ofstream &of,
double time)
333 if (verbose || !use_plot_file) {
334 std::cout << method << time << std::endl;
338 int main(
int argc,
const char *argv[])
341 #if defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_LAPACK) || (VISP_HAVE_OPENCV_VERSION >= 0x020101) || \ 342 defined(VISP_HAVE_GSL) 343 unsigned int nb_matrices = 100;
344 unsigned int nb_iterations = 10;
345 unsigned int nb_rows = 6;
346 unsigned int nb_cols = 6;
347 bool verbose =
false;
348 std::string plotfile(
"plot-svd.csv");
349 bool use_plot_file =
false;
353 if (getOptions(argc, argv, nb_matrices, nb_iterations, use_plot_file, plotfile, nb_rows, nb_cols, verbose) ==
359 of.open(plotfile.c_str());
363 #if defined(VISP_HAVE_LAPACK) 364 of <<
"\"SVD Lapack\"" 367 #if defined(VISP_HAVE_EIGEN3) 368 of <<
"\"SVD Eigen3\"" 371 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101) 372 of <<
"\"SVD OpenCV\"" 375 #if defined(VISP_HAVE_GSL) 382 int ret = EXIT_SUCCESS;
383 for (
unsigned int iter = 0; iter < nb_iterations; iter++) {
384 std::vector<vpMatrix> bench_random_matrices;
385 create_bench_random_matrix(nb_matrices, nb_rows, nb_cols, verbose, bench_random_matrices);
391 #if defined(VISP_HAVE_LAPACK) 392 ret += test_svd_lapack(verbose, bench_random_matrices, time);
393 save_time(
"SVD (Lapack): ", verbose, use_plot_file, of, time);
396 #if defined(VISP_HAVE_EIGEN3) 397 ret += test_svd_eigen3(verbose, bench_random_matrices, time);
398 save_time(
"SVD (Eigen3): ", verbose, use_plot_file, of, time);
401 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101) 402 ret += test_svd_opencv(verbose, bench_random_matrices, time);
403 save_time(
"SVD (OpenCV): ", verbose, use_plot_file, of, time);
406 #if defined(VISP_HAVE_GSL) 407 ret += test_svd_gsl(verbose, bench_random_matrices, time);
408 save_time(
"SVD (GSL): ", verbose, use_plot_file, of, time);
415 std::cout <<
"Result saved in " << plotfile << std::endl;
418 if (ret == EXIT_SUCCESS) {
419 std::cout <<
"Test succeed" << std::endl;
421 std::cout <<
"Test failed" << std::endl;
428 std::cout <<
"Test does nothing since you dont't have Eigen3, Lapack, " 429 "OpenCV or GSL 3rd party" Implementation of a matrix and operations on matrices.
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true, const 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)
void diag(const double &val=1.0)
unsigned int getRows() const
double euclideanNorm() const
const std::string & getStringMessage(void) const
Send a reference (constant) related the error message (can be empty).