50 #include <visp/vpTime.h>
52 #include <visp/vpMatrix.h>
53 #include <visp/vpColVector.h>
54 #include <visp/vpParseArgv.h>
62 #define GETOPTARGS "n:i:pf:r:c:vh"
64 void usage(
const char *name,
const char *badparam);
65 bool getOptions(
int argc,
const char **argv,
66 unsigned int& nb_matrices,
unsigned int& nb_iterations,
67 bool& use_plot_file, std::string& plotfile,
68 unsigned int& nbrows,
unsigned int& nbcols,
bool& verbose);
69 void writeTime(
const char *name,
double time);
70 vpMatrix makeRandomMatrix(
unsigned int nbrows,
unsigned int nbcols);
80 void usage(
const char *name,
const char *badparam)
83 Test matrix inversions\n\
84 using LU, QR and Cholesky methods as well as Pseudo-inverse.\n\
85 Outputs a comparison of these methods.\n\
88 %s [-n <number of matrices>] [-f <plot filename>]\n\
89 [-r <number of rows>] [-c <number of columns>]\n\
90 [-i <number of iterations>] [-p] [-h]\n", name);
94 -n <number of matrices> \n\
95 Number of matrices inverted during each test loop.\n\
97 -i <number of iterations> \n\
98 Number of iterations of the test.\n\
100 -f <plot filename> \n\
101 Set output path for plot output.\n\
102 The plot logs the times of \n\
103 the different inversion methods: \n\
104 QR,LU,Cholesky and Pseudo-inverse.\n\
106 -r <number of rows>\n\
107 Number of rows of the automatically generated matrices \n\
110 -c <number of columns>\n\
111 Number of colums of the automatically generated matrices \n\
115 Plot into filename in the gnuplot format. \n\
116 If this option is used, tests results will be logged \n\
117 into a filename specified with -f.\n\
120 Print the help.\n\n");
123 fprintf(stderr,
"ERROR: \n" );
124 fprintf(stderr,
"\nBad parameter [%s]\n", badparam);
135 bool getOptions(
int argc,
const char **argv,
136 unsigned int& nb_matrices,
unsigned int& nb_iterations,
137 bool& use_plot_file, std::string& plotfile,
138 unsigned int& nbrows,
unsigned int& nbcols,
bool& verbose)
145 case 'h': usage(argv[0], NULL);
return false;
break;
147 nb_matrices = (
unsigned int)atoi(optarg_);
150 nb_iterations = (
unsigned int)atoi(optarg_);
154 use_plot_file =
true;
157 use_plot_file =
true;
160 nbrows = (
unsigned int)atoi(optarg_);
163 nbcols = (
unsigned int)atoi(optarg_);
169 usage(argv[0], optarg_);
174 if ((c == 1) || (c == -1)) {
176 usage(argv[0], NULL);
177 std::cerr <<
"ERROR: " << std::endl;
178 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
185 void writeTime(
const char *name,
double time)
187 std::cout << name <<
" time=" << time <<
" ms." << std::endl;
190 vpMatrix makeRandomMatrix(
unsigned int nbrows,
unsigned int nbcols)
195 for (
unsigned int i=0 ; i < A.
getRows() ; i++)
196 for (
unsigned int j=0 ; j < A.
getCols() ; j++)
197 A[i][j] = (
double)rand()/(double)RAND_MAX;
203 main(
int argc,
const char ** argv)
205 #ifdef VISP_HAVE_LAPACK
207 unsigned int nb_matrices=1000;
208 unsigned int nb_iterations=10;
209 unsigned int nb_rows = 6;
210 unsigned int nb_cols = 6;
211 bool verbose =
false;
212 std::string plotfile(
"plot.txt");
213 bool use_plot_file=
false;
216 double t, qr_time, lu_time,pi_time,chol_time;
218 if (getOptions(argc, argv, nb_matrices,nb_iterations,use_plot_file,plotfile,nb_rows,nb_cols,verbose) ==
false) {
223 of.open(plotfile.c_str());
226 for(
unsigned int iter=0;iter<nb_iterations;iter++){
227 std::vector<vpMatrix> benchQR;
228 std::vector<vpMatrix> benchLU;
229 std::vector<vpMatrix> benchCholesky;
230 std::vector<vpMatrix> benchPseudoInverse;
232 std::cout <<
"********* generating matrices for iteration " << iter <<
"." << std::endl;
233 for(
unsigned int i=0;i<nb_matrices;i++){
237 for(cur=makeRandomMatrix(nb_rows,nb_cols);std::abs(det=cur.
AtA().
det())<.01;cur = makeRandomMatrix(nb_rows,nb_cols))
239 std::cout <<
"Generated random matrix A*tA=" << std::endl << cur.
AtA() << std::endl;
240 std::cout <<
"generated random matrix not invertibleL: det="<<det<<
". Retrying..." << std::endl;
242 benchCholesky.push_back(cur);
243 benchQR.push_back(cur);
244 benchLU.push_back(cur);
245 benchPseudoInverse.push_back(cur);
249 std::cout <<
"\t Inverting " << benchCholesky[0].
AtA().
getRows() <<
"x" << benchCholesky[0].AtA().getCols() <<
" matrix using cholesky decomposition." << std::endl;
251 for(
unsigned int i=0;i<nb_matrices;i++){
252 benchCholesky[i]=benchCholesky[i].AtA().inverseByCholesky()*benchCholesky[i].transpose();
257 std::cout <<
"\t Inverting " << benchLU[0].AtA().getRows() <<
"x" << benchLU[0].AtA().getCols() <<
" matrix using LU decomposition." << std::endl;
259 for(
unsigned int i=0;i<nb_matrices;i++)
260 benchLU[i] = benchLU[i].AtA().inverseByLU()*benchLU[i].transpose();
264 std::cout <<
"\t Inverting " << benchQR[0].AtA().getRows() <<
"x" << benchQR[0].AtA().getCols() <<
" matrix using QR decomposition." << std::endl;
266 for(
unsigned int i=0;i<nb_matrices;i++){
267 benchQR[i]=benchQR[i].AtA().inverseByQR()*benchQR[i].transpose();
272 std::cout <<
"\t Inverting " << benchPseudoInverse[0].AtA().getRows() <<
"x" << benchPseudoInverse[0].AtA().getCols() <<
" matrix while computing pseudo-inverse." << std::endl;
274 for(
unsigned int i=0;i<nb_matrices;i++){
275 benchPseudoInverse[i]=benchPseudoInverse[i].pseudoInverse();
279 double avg_err_lu_qr=0.;
280 double avg_err_lu_pi=0.;
281 double avg_err_lu_chol=0.;
282 double avg_err_qr_pi=0.;
283 double avg_err_qr_chol=0.;
284 double avg_err_pi_chol=0.;
286 for(
unsigned int i=0;i<nb_matrices;i++){
287 avg_err_lu_qr+= (benchQR[i]-benchLU[i]).euclideanNorm();
288 avg_err_lu_pi+= (benchPseudoInverse[i]-benchLU[i]).euclideanNorm();
289 avg_err_qr_pi+= (benchPseudoInverse[i]-benchQR[i]).euclideanNorm();
290 avg_err_qr_chol+= (benchCholesky[i]-benchQR[i]).euclideanNorm();
291 avg_err_lu_chol+= (benchCholesky[i]-benchLU[i]).euclideanNorm();
292 avg_err_pi_chol+= (benchCholesky[i]-benchPseudoInverse[i]).euclideanNorm();
295 avg_err_lu_qr/=nb_matrices;
296 avg_err_lu_pi/=nb_matrices;
297 avg_err_qr_pi/=nb_matrices;
300 of << iter <<
"\t" << lu_time <<
"\t" << qr_time <<
"\t" << pi_time <<
"\t" << chol_time <<
"\t" << avg_err_lu_qr <<
"\t" << avg_err_qr_pi <<
"\t" << avg_err_lu_pi <<
"\t" << avg_err_qr_chol <<
"\t" << avg_err_lu_chol <<
"\t" << avg_err_pi_chol << std::endl;
302 if(verbose || !use_plot_file){
303 writeTime(
"LU",lu_time);
304 writeTime(
"QR",qr_time);
305 writeTime(
"Pseudo-inverse",pi_time);
306 writeTime(
"Cholesky",chol_time);
312 std::cout <<
"Catch an exception: " << e << std::endl;
319 std::cout <<
"You don't have lapack installed" << std::endl;
Definition of the vpMatrix class.
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
error that can be emited by ViSP classes.
static double measureTimeMs()
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
double det(vpDetMethod method=LU_DECOMPOSITION) const
unsigned int getCols() const
Return the number of columns of the matrix.
unsigned int getRows() const
Return the number of rows of the matrix.