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
58 void usage(
const char *name,
const char *badparam)
61 Test matrix inversions\n\
62 using LU, QR and Cholesky methods as well as Pseudo-inverse.\n\
63 Outputs a comparison of these methods.\n\
66 %s [-n <number of matrices>] [-f <plot filename>]\n\
67 [-R <number of rows>] [-C <number of columns>]\n\
68 [-i <number of iterations>] [-p] [-h]\n",
73 -n <number of matrices> \n\
74 Number of matrices inverted during each test loop.\n\
76 -i <number of iterations> \n\
77 Number of iterations of the test.\n\
79 -f <plot filename> \n\
80 Set output path for plot output.\n\
81 The plot logs the times of \n\
82 the different inversion methods: \n\
83 QR,LU,Cholesky and Pseudo-inverse.\n\
85 -R <number of rows>\n\
86 Number of rows of the automatically generated matrices \n\
89 -C <number of columns>\n\
90 Number of colums of the automatically generated matrices \n\
94 Plot into filename in the gnuplot format. \n\
95 If this option is used, tests results will be logged \n\
96 into a filename specified with -f.\n\
99 Print the help.\n\n");
102 fprintf(stderr,
"ERROR: \n");
103 fprintf(stderr,
"\nBad parameter [%s]\n", badparam);
114 bool getOptions(
int argc,
const char **argv,
unsigned int &nb_matrices,
unsigned int &nb_iterations,
115 bool &use_plot_file, std::string &plotfile,
unsigned int &nbrows,
unsigned int &nbcols,
bool &verbose)
123 usage(argv[0],
nullptr);
127 nb_matrices = (
unsigned int)atoi(optarg_);
130 nb_iterations = (
unsigned int)atoi(optarg_);
134 use_plot_file =
true;
137 use_plot_file =
true;
140 nbrows = (
unsigned int)atoi(optarg_);
143 nbcols = (
unsigned int)atoi(optarg_);
154 usage(argv[0], optarg_);
160 if ((c == 1) || (c == -1)) {
162 usage(argv[0],
nullptr);
163 std::cerr <<
"ERROR: " << std::endl;
164 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
171 vpMatrix make_random_matrix(
unsigned int nbrows,
unsigned int nbcols)
176 for (
unsigned int i = 0; i < A.
getRows(); i++)
177 for (
unsigned int j = 0; j < A.
getCols(); j++)
178 A[i][j] = (
double)rand() / (double)RAND_MAX;
182 void create_bench(
unsigned int nb_matrices,
unsigned int nb_rows,
unsigned int nb_cols,
bool verbose,
183 std::vector<vpMatrix> &bench)
186 std::cout <<
"Create a bench of " << nb_matrices <<
" " << nb_rows <<
" by " << nb_cols <<
" matrices" << std::endl;
188 for (
unsigned int i = 0; i < nb_matrices; i++) {
189 vpMatrix M = make_random_matrix(nb_rows, nb_cols);
194 void test_det_default(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
197 std::cout <<
"Test determinant using default method" << std::endl;
200 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
202 result.resize(bench.size());
204 for (
unsigned int i = 0; i < bench.size(); i++) {
205 result[i] = bench[i].AtA().det();
210 #if defined(VISP_HAVE_EIGEN3)
211 void test_det_eigen3(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
214 std::cout <<
"Test determinant using Eigen3 3rd party" << std::endl;
217 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
219 result.resize(bench.size());
221 for (
unsigned int i = 0; i < bench.size(); i++) {
222 result[i] = bench[i].AtA().detByLUEigen3();
228 #if defined(VISP_HAVE_LAPACK)
229 void test_det_lapack(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
232 std::cout <<
"Test determinant using Lapack 3rd party" << std::endl;
235 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
237 result.resize(bench.size());
239 for (
unsigned int i = 0; i < bench.size(); i++) {
240 result[i] = bench[i].AtA().detByLULapack();
246 #if defined(VISP_HAVE_OPENCV)
247 void test_det_opencv(
bool verbose,
const std::vector<vpMatrix> &bench,
double &time, std::vector<double> &result)
250 std::cout <<
"Test determinant using OpenCV 3rd party" << std::endl;
253 std::cout <<
" Matrix size: " << bench[0].AtA().getRows() <<
"x" << bench[0].AtA().getCols() << std::endl;
255 result.resize(bench.size());
257 for (
unsigned int i = 0; i < bench.size(); i++) {
258 result[i] = bench[i].AtA().detByLUOpenCV();
264 void save_time(
const std::string &method,
bool verbose,
bool use_plot_file, std::ofstream &of,
double time)
268 if (verbose || !use_plot_file) {
269 std::cout << method << time << std::endl;
273 int main(
int argc,
const char *argv[])
276 #if defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_OPENCV)
277 unsigned int nb_matrices = 1000;
278 unsigned int nb_iterations = 10;
279 unsigned int nb_rows = 6;
280 unsigned int nb_cols = 6;
281 bool verbose =
false;
282 std::string plotfile(
"plot-det.csv");
283 bool use_plot_file =
false;
287 if (getOptions(argc, argv, nb_matrices, nb_iterations, use_plot_file, plotfile, nb_rows, nb_cols, verbose) ==
293 of.open(plotfile.c_str());
297 of <<
"\"Determinant default\""
300 #if defined(VISP_HAVE_LAPACK)
301 of <<
"\"Determinant Lapack\""
304 #if defined(VISP_HAVE_EIGEN3)
305 of <<
"\"Determinant Eigen3\""
308 #if defined(VISP_HAVE_OPENCV)
309 of <<
"\"Determinant OpenCV\""
315 int ret = EXIT_SUCCESS;
316 for (
unsigned int iter = 0; iter < nb_iterations; iter++) {
317 std::vector<vpMatrix> bench;
318 create_bench(nb_matrices, nb_rows, nb_cols, verbose, bench);
325 std::vector<double> result_default;
326 test_det_default(verbose, bench, time, result_default);
327 save_time(
"Determinant default: ", verbose, use_plot_file, of, time);
329 #if defined(VISP_HAVE_LAPACK)
330 std::vector<double> result_lapack;
331 test_det_lapack(verbose, bench, time, result_lapack);
332 save_time(
"Determinant by Lapack: ", verbose, use_plot_file, of, time);
335 #if defined(VISP_HAVE_EIGEN3)
336 std::vector<double> result_eigen3;
337 test_det_eigen3(verbose, bench, time, result_eigen3);
338 save_time(
"Determinant by Eigen3: ", verbose, use_plot_file, of, time);
341 #if defined(VISP_HAVE_OPENCV)
342 std::vector<double> result_opencv;
343 test_det_opencv(verbose, bench, time, result_opencv);
344 save_time(
"Determinant by OpenCV: ", verbose, use_plot_file, of, time);
350 #if defined(VISP_HAVE_LAPACK) && defined(VISP_HAVE_OPENCV)
352 for (
unsigned int i = 0; i < bench.size(); i++) {
353 if (std::fabs(result_lapack[i] - result_opencv[i]) > 1e-6) {
354 std::cout <<
"Determinant differ between Lapack and OpenCV: " << result_lapack[i] <<
" " << result_opencv[i]
360 #if defined(VISP_HAVE_EIGEN3) && defined(VISP_HAVE_OPENCV)
362 for (
unsigned int i = 0; i < bench.size(); i++) {
363 if (std::fabs(result_eigen3[i] - result_opencv[i]) > 1e-6) {
364 std::cout <<
"Determinant differ between Eigen3 and OpenCV: " << result_eigen3[i] <<
" " << result_opencv[i]
370 #if defined(VISP_HAVE_EIGEN3) && defined(VISP_HAVE_LAPACK)
372 for (
unsigned int i = 0; i < bench.size(); i++) {
373 if (std::fabs(result_eigen3[i] - result_lapack[i]) > 1e-6) {
374 std::cout <<
"Determinant differ between Eigen3 and Lapack: " << result_eigen3[i] <<
" " << result_lapack[i]
383 std::cout <<
"Result saved in " << plotfile << std::endl;
386 if (ret == EXIT_SUCCESS) {
387 std::cout <<
"Test succeed" << std::endl;
390 std::cout <<
"Test failed" << std::endl;
397 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()