41 #include <visp3/core/vpMatrix.h>
42 #include <visp3/core/vpTime.h>
43 #include <visp3/io/vpParseArgv.h>
46 #define GETOPTARGS "cdn:i:pf:R:C:vh"
56 void usage(
const char *name,
const char *badparam)
59 Test matrix inversions\n\
60 using LU, QR and Cholesky methods as well as Pseudo-inverse.\n\
61 Outputs a comparison of these methods.\n\
64 %s [-n <number of matrices>] [-f <plot filename>]\n\
65 [-R <number of rows>] [-C <number of columns>]\n\
66 [-i <number of iterations>] [-p] [-h]\n",
71 -n <number of matrices> \n\
72 Number of matrices inverted during each test loop.\n\
74 -i <number of iterations> \n\
75 Number of iterations of the test.\n\
77 -f <plot filename> \n\
78 Set output path for plot output.\n\
79 The plot logs the times of \n\
80 the different inversion methods: \n\
81 QR,LU,Cholesky and Pseudo-inverse.\n\
83 -R <number of rows>\n\
84 Number of rows of the automatically generated matrices \n\
87 -C <number of columns>\n\
88 Number of colums of the automatically generated matrices \n\
92 Plot into filename in the gnuplot format. \n\
93 If this option is used, tests results will be logged \n\
94 into a filename specified with -f.\n\
97 Print the help.\n\n");
100 fprintf(stderr,
"ERROR: \n");
101 fprintf(stderr,
"\nBad parameter [%s]\n", badparam);
112 bool getOptions(
int argc,
const char **argv,
unsigned int &nb_matrices,
unsigned int &nb_iterations,
113 bool &use_plot_file, std::string &plotfile,
unsigned int &nbrows,
unsigned int &nbcols,
bool &verbose)
121 usage(argv[0],
nullptr);
125 nb_matrices = (
unsigned int)atoi(optarg_);
128 nb_iterations = (
unsigned int)atoi(optarg_);
132 use_plot_file =
true;
135 use_plot_file =
true;
138 nbrows = (
unsigned int)atoi(optarg_);
141 nbcols = (
unsigned int)atoi(optarg_);
152 usage(argv[0], optarg_);
158 if ((c == 1) || (c == -1)) {
160 usage(argv[0],
nullptr);
161 std::cerr <<
"ERROR: " << std::endl;
162 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
169 vpMatrix make_random_matrix(
unsigned int nbrows,
unsigned int nbcols)
174 for (
unsigned int i = 0; i < A.
getRows(); i++)
175 for (
unsigned int j = 0; j < A.
getCols(); j++)
176 A[i][j] = (
double)rand() / (double)RAND_MAX;
180 void create_bench(
unsigned int nb_matrices,
unsigned int nb_rows,
unsigned int nb_cols,
bool verbose,
181 std::vector<vpMatrix> &bench)
184 std::cout <<
"Create a bench of " << nb_matrices <<
" " << nb_rows <<
" by " << nb_cols <<
" matrices" << std::endl;
186 for (
unsigned int i = 0; i < nb_matrices; i++) {
187 vpMatrix M = make_random_matrix(nb_rows, nb_cols);
192 void test_det_default(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
195 std::cout <<
"Test determinant using default method" << std::endl;
198 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
200 result.resize(bench.size());
202 for (
unsigned int i = 0; i < bench.size(); i++) {
203 result[i] = bench[i].AtA().det();
208 #if defined(VISP_HAVE_EIGEN3)
209 void test_det_eigen3(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
212 std::cout <<
"Test determinant using Eigen3 3rd party" << std::endl;
215 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
217 result.resize(bench.size());
219 for (
unsigned int i = 0; i < bench.size(); i++) {
220 result[i] = bench[i].AtA().detByLUEigen3();
226 #if defined(VISP_HAVE_LAPACK)
227 void test_det_lapack(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
230 std::cout <<
"Test determinant using Lapack 3rd party" << std::endl;
233 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
235 result.resize(bench.size());
237 for (
unsigned int i = 0; i < bench.size(); i++) {
238 result[i] = bench[i].AtA().detByLULapack();
244 #if defined(VISP_HAVE_OPENCV)
245 void test_det_opencv(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
248 std::cout <<
"Test determinant using OpenCV 3rd party" << std::endl;
251 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
253 result.resize(bench.size());
255 for (
unsigned int i = 0; i < bench.size(); i++) {
256 result[i] = bench[i].AtA().detByLUOpenCV();
262 void save_time(
const std::string &method,
bool verbose,
bool use_plot_file, std::ofstream &of,
double time)
266 if (verbose || !use_plot_file) {
267 std::cout << method << time << std::endl;
271 int main(
int argc,
const char *argv[])
274 #if defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_OPENCV)
275 unsigned int nb_matrices = 1000;
276 unsigned int nb_iterations = 10;
277 unsigned int nb_rows = 6;
278 unsigned int nb_cols = 6;
279 bool verbose =
false;
280 std::string plotfile(
"plot-det.csv");
281 bool use_plot_file =
false;
285 if (getOptions(argc, argv, nb_matrices, nb_iterations, use_plot_file, plotfile, nb_rows, nb_cols, verbose) ==
291 of.open(plotfile.c_str());
295 of <<
"\"Determinant default\""
298 #if defined(VISP_HAVE_LAPACK)
299 of <<
"\"Determinant Lapack\""
302 #if defined(VISP_HAVE_EIGEN3)
303 of <<
"\"Determinant Eigen3\""
306 #if defined(VISP_HAVE_OPENCV)
307 of <<
"\"Determinant OpenCV\""
313 int ret = EXIT_SUCCESS;
314 for (
unsigned int iter = 0; iter < nb_iterations; iter++) {
315 std::vector<vpMatrix> bench;
316 create_bench(nb_matrices, nb_rows, nb_cols, verbose, bench);
323 std::vector<double> result_default;
324 test_det_default(verbose, bench, time, result_default);
325 save_time(
"Determinant default: ", verbose, use_plot_file, of, time);
327 #if defined(VISP_HAVE_LAPACK)
328 std::vector<double> result_lapack;
329 test_det_lapack(verbose, bench, time, result_lapack);
330 save_time(
"Determinant by Lapack: ", verbose, use_plot_file, of, time);
333 #if defined(VISP_HAVE_EIGEN3)
334 std::vector<double> result_eigen3;
335 test_det_eigen3(verbose, bench, time, result_eigen3);
336 save_time(
"Determinant by Eigen3: ", verbose, use_plot_file, of, time);
339 #if defined(VISP_HAVE_OPENCV)
340 std::vector<double> result_opencv;
341 test_det_opencv(verbose, bench, time, result_opencv);
342 save_time(
"Determinant by OpenCV: ", verbose, use_plot_file, of, time);
348 #if defined(VISP_HAVE_LAPACK) && defined(VISP_HAVE_OPENCV)
350 for (
unsigned int i = 0; i < bench.size(); i++) {
351 if (std::fabs(result_lapack[i] - result_opencv[i]) > 1e-6) {
352 std::cout <<
"Determinant differ between Lapack and OpenCV: " << result_lapack[i] <<
" " << result_opencv[i]
358 #if defined(VISP_HAVE_EIGEN3) && defined(VISP_HAVE_OPENCV)
360 for (
unsigned int i = 0; i < bench.size(); i++) {
361 if (std::fabs(result_eigen3[i] - result_opencv[i]) > 1e-6) {
362 std::cout <<
"Determinant differ between Eigen3 and OpenCV: " << result_eigen3[i] <<
" " << result_opencv[i]
368 #if defined(VISP_HAVE_EIGEN3) && defined(VISP_HAVE_LAPACK)
370 for (
unsigned int i = 0; i < bench.size(); i++) {
371 if (std::fabs(result_eigen3[i] - result_lapack[i]) > 1e-6) {
372 std::cout <<
"Determinant differ between Eigen3 and Lapack: " << result_eigen3[i] <<
" " << result_lapack[i]
381 std::cout <<
"Result saved in " << plotfile << std::endl;
384 if (ret == EXIT_SUCCESS) {
385 std::cout <<
"Test succeed" << std::endl;
387 std::cout <<
"Test failed" << std::endl;
394 std::cout <<
"Test does nothing since you dont't have Lapack, Eigen3 or OpenCV 3rd party" << 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.
const std::string & getStringMessage() const
Implementation of a matrix and operations on matrices.
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
VISP_EXPORT double measureTimeMs()