39#include <visp3/core/vpMatrix.h>
40#include <visp3/core/vpTime.h>
41#include <visp3/io/vpParseArgv.h>
44#define GETOPTARGS "cdn:i:pf:R:C:vh"
46#ifdef ENABLE_VISP_NAMESPACE
50void usage(
const char *name,
const char *badparam);
51bool getOptions(
int argc,
const char **argv,
unsigned int &nb_matrices,
unsigned int &nb_iterations,
52 bool &use_plot_file, std::string &plotfile,
unsigned int &nbrows,
unsigned int &nbcols,
bool &verbose);
53vpMatrix make_random_matrix(
unsigned int nbrows,
unsigned int nbcols);
54void create_bench(
unsigned int nb_matrices,
unsigned int nb_rows,
unsigned int nb_cols,
bool verbose,
55 std::vector<vpMatrix> &bench);
56void test_det_default(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result);
57void save_time(
const std::string &method,
bool verbose,
bool use_plot_file, std::ofstream &of,
double time);
58#if defined(VISP_HAVE_EIGEN3)
59void test_det_eigen3(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result);
61#if defined(VISP_HAVE_LAPACK)
62void test_det_lapack(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result);
64#if defined(VISP_HAVE_OPENCV)
65void test_det_opencv(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result);
74void usage(
const char *name,
const char *badparam)
77Test matrix inversions\n\
78using LU, QR and Cholesky methods as well as Pseudo-inverse.\n\
79Outputs a comparison of these methods.\n\
82 %s [-n <number of matrices>] [-f <plot filename>]\n\
83 [-R <number of rows>] [-C <number of columns>]\n\
84 [-i <number of iterations>] [-p] [-h]\n",
89 -n <number of matrices> \n\
90 Number of matrices inverted during each test loop.\n\
92 -i <number of iterations> \n\
93 Number of iterations of the test.\n\
95 -f <plot filename> \n\
96 Set output path for plot output.\n\
97 The plot logs the times of \n\
98 the different inversion methods: \n\
99 QR,LU,Cholesky and Pseudo-inverse.\n\
101 -R <number of rows>\n\
102 Number of rows of the automatically generated matrices \n\
105 -C <number of columns>\n\
106 Number of colums of the automatically generated matrices \n\
110 Plot into filename in the gnuplot format. \n\
111 If this option is used, tests results will be logged \n\
112 into a filename specified with -f.\n\
115 Print the help.\n\n");
118 fprintf(stderr,
"ERROR: \n");
119 fprintf(stderr,
"\nBad parameter [%s]\n", badparam);
130bool getOptions(
int argc,
const char **argv,
unsigned int &nb_matrices,
unsigned int &nb_iterations,
131 bool &use_plot_file, std::string &plotfile,
unsigned int &nbrows,
unsigned int &nbcols,
bool &verbose)
139 usage(argv[0],
nullptr);
142 nb_matrices =
static_cast<unsigned int>(atoi(optarg_));
145 nb_iterations =
static_cast<unsigned int>(atoi(optarg_));
149 use_plot_file =
true;
152 use_plot_file =
true;
155 nbrows =
static_cast<unsigned int>(atoi(optarg_));
158 nbcols =
static_cast<unsigned int>(atoi(optarg_));
169 usage(argv[0], optarg_);
174 if ((c == 1) || (c == -1)) {
176 usage(argv[0],
nullptr);
177 std::cerr <<
"ERROR: " << std::endl;
178 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
185vpMatrix make_random_matrix(
unsigned int nbrows,
unsigned int nbcols)
190 for (
unsigned int i = 0;
i < A.
getRows();
i++)
191 for (
unsigned int j = 0;
j < A.
getCols();
j++)
192 A[i][j] =
static_cast<double>(rand()) /
static_cast<double>(RAND_MAX);
196void create_bench(
unsigned int nb_matrices,
unsigned int nb_rows,
unsigned int nb_cols,
bool verbose,
197 std::vector<vpMatrix> &bench)
200 std::cout <<
"Create a bench of " << nb_matrices <<
" " << nb_rows <<
" by " << nb_cols <<
" matrices" << std::endl;
202 for (
unsigned int i = 0;
i < nb_matrices;
i++) {
203 vpMatrix M = make_random_matrix(nb_rows, nb_cols);
208void test_det_default(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
211 std::cout <<
"Test determinant using default method" << std::endl;
214 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
216 result.resize(bench.size());
218 for (
unsigned int i = 0;
i < bench.size();
i++) {
219 result[
i] = bench[
i].AtA().det();
224#if defined(VISP_HAVE_EIGEN3)
225void test_det_eigen3(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
228 std::cout <<
"Test determinant using Eigen3 3rd party" << std::endl;
231 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
233 result.resize(bench.size());
235 for (
unsigned int i = 0;
i < bench.size();
i++) {
236 result[
i] = bench[
i].AtA().detByLUEigen3();
242#if defined(VISP_HAVE_LAPACK)
243void test_det_lapack(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
246 std::cout <<
"Test determinant using Lapack 3rd party" << std::endl;
249 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
251 result.resize(bench.size());
253 for (
unsigned int i = 0;
i < bench.size();
i++) {
254 result[
i] = bench[
i].AtA().detByLULapack();
260#if defined(VISP_HAVE_OPENCV)
261void test_det_opencv(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
264 std::cout <<
"Test determinant using OpenCV 3rd party" << std::endl;
267 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
269 result.resize(bench.size());
271 for (
unsigned int i = 0;
i < bench.size();
i++) {
272 result[
i] = bench[
i].AtA().detByLUOpenCV();
278void save_time(
const std::string &method,
bool verbose,
bool use_plot_file, std::ofstream &of,
double time)
282 if (verbose || !use_plot_file) {
283 std::cout << method << time << std::endl;
287int main(
int argc,
const char *argv[])
290#if defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_OPENCV)
291 unsigned int nb_matrices = 1000;
292 unsigned int nb_iterations = 10;
293 unsigned int nb_rows = 6;
294 unsigned int nb_cols = 6;
295 bool verbose =
false;
296 std::string plotfile(
"plot-det.csv");
297 bool use_plot_file =
false;
301 if (getOptions(argc, argv, nb_matrices, nb_iterations, use_plot_file, plotfile, nb_rows, nb_cols, verbose) ==
307 of.open(plotfile.c_str());
311 of <<
"\"Determinant default\""
314#if defined(VISP_HAVE_LAPACK)
315 of <<
"\"Determinant Lapack\""
318#if defined(VISP_HAVE_EIGEN3)
319 of <<
"\"Determinant Eigen3\""
322#if defined(VISP_HAVE_OPENCV)
323 of <<
"\"Determinant OpenCV\""
329 int ret = EXIT_SUCCESS;
330 for (
unsigned int iter = 0;
iter < nb_iterations;
iter++) {
331 std::vector<vpMatrix> bench;
332 create_bench(nb_matrices, nb_rows, nb_cols, verbose, bench);
339 std::vector<double> result_default;
340 test_det_default(verbose, bench, time, result_default);
341 save_time(
"Determinant default: ", verbose, use_plot_file, of, time);
343#if defined(VISP_HAVE_LAPACK)
344 std::vector<double> result_lapack;
345 test_det_lapack(verbose, bench, time, result_lapack);
346 save_time(
"Determinant by Lapack: ", verbose, use_plot_file, of, time);
349#if defined(VISP_HAVE_EIGEN3)
350 std::vector<double> result_eigen3;
351 test_det_eigen3(verbose, bench, time, result_eigen3);
352 save_time(
"Determinant by Eigen3: ", verbose, use_plot_file, of, time);
355#if defined(VISP_HAVE_OPENCV)
356 std::vector<double> result_opencv;
357 test_det_opencv(verbose, bench, time, result_opencv);
358 save_time(
"Determinant by OpenCV: ", verbose, use_plot_file, of, time);
364#if defined(VISP_HAVE_LAPACK) && defined(VISP_HAVE_OPENCV)
366 for (
unsigned int i = 0;
i < bench.size();
i++) {
367 if (std::fabs(result_lapack[i] - result_opencv[i]) > 1e-6) {
368 std::cout <<
"Determinant differ between Lapack and OpenCV: " << result_lapack[
i] <<
" " << result_opencv[
i]
374#if defined(VISP_HAVE_EIGEN3) && defined(VISP_HAVE_OPENCV)
376 for (
unsigned int i = 0;
i < bench.size();
i++) {
377 if (std::fabs(result_eigen3[i] - result_opencv[i]) > 1e-6) {
378 std::cout <<
"Determinant differ between Eigen3 and OpenCV: " << result_eigen3[
i] <<
" " << result_opencv[
i]
384#if defined(VISP_HAVE_EIGEN3) && defined(VISP_HAVE_LAPACK)
386 for (
unsigned int i = 0;
i < bench.size();
i++) {
387 if (std::fabs(result_eigen3[i] - result_lapack[i]) > 1e-6) {
388 std::cout <<
"Determinant differ between Eigen3 and Lapack: " << result_eigen3[
i] <<
" " << result_lapack[
i]
397 std::cout <<
"Result saved in " << plotfile << std::endl;
400 if (ret == EXIT_SUCCESS) {
401 std::cout <<
"Test succeed" << std::endl;
404 std::cout <<
"Test failed" << std::endl;
411 std::cout <<
"Test does nothing since you dont't have Lapack, Eigen3 or OpenCV 3rd party" << std::endl;
416 std::cout <<
"Catch an exception: " <<
e.getStringMessage() << std::endl;
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.
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
VISP_EXPORT double measureTimeMs()