ViSP  2.9.0
testSvd.cpp
1 /****************************************************************************
2  *
3  * $Id: testSvd.cpp 4658 2014-02-09 09:50:14Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Test various svd decompositions.
36  *
37  * Authors:
38  * Eric Marchand
39  * Fabien Spindler
40  *
41  *****************************************************************************/
42 
43 
51 #include <visp/vpTime.h>
52 
53 #include <visp/vpMatrix.h>
54 #include <visp/vpColVector.h>
55 #include <visp/vpParseArgv.h>
56 #include <vector>
57 #include <algorithm>
58 #include <stdlib.h>
59 #include <stdio.h>
60 // List of allowed command line options
61 #define GETOPTARGS "h"
62 
63 void usage(const char *name, const char *badparam);
64 bool getOptions(int argc, const char **argv);
65 bool testSvdOpenCvGSLCoherence(double epsilon);
66 #ifdef VISP_HAVE_GSL
67 bool testRandom(double epsilon);
68 #endif
69 
75 void usage(const char *name, const char *badparam)
76 {
77  fprintf(stdout, "\n\
78 Test various svd decompositions.\n\
79 \n\
80 SYNOPSIS\n\
81  %s [-h]\n", name);
82 
83  fprintf(stdout, "\n\
84 OPTIONS: Default\n\
85  -h\n\
86  Print the help.\n");
87 
88  if (badparam)
89  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
90 }
98 bool getOptions(int argc, const char **argv)
99 {
100  const char *optarg_;
101  int c;
102  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
103 
104  switch (c) {
105  case 'h': usage(argv[0], NULL); return false; break;
106 
107  default:
108  usage(argv[0], optarg_);
109  return false; break;
110  }
111  }
112 
113  if ((c == 1) || (c == -1)) {
114  // standalone param or error
115  usage(argv[0], NULL);
116  std::cerr << "ERROR: " << std::endl;
117  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
118  return false;
119  }
120 
121  return true;
122 }
123 #define abs(x) ((x) < 0 ? - (x) : (x))
124 #ifdef VISP_HAVE_GSL
125 
126 bool testRandom(double epsilon)
127 {
128  vpMatrix L0(6,6);
129  vpMatrix L1(6,6);
130 
131  for (unsigned int i=0 ; i < L0.getRows() ; i++)
132  for (unsigned int j=0 ; j < L0.getCols() ; j++)
133  L1[i][j] = L0[i][j] = (double)rand()/(double)RAND_MAX;
134 
135  vpColVector W0(L0.getCols()) ;
136  vpMatrix V0(L0.getCols(), L0.getCols()) ;
137  vpColVector W1(L1.getCols()) ;
138  vpMatrix V1(L1.getCols(), L1.getCols()) ;
139 
140  L0.svdNr(W0,V0);
141  L1.svdGsl(W1,V1);
142 
143  vpColVector _W0 = vpColVector::sort(W0);
144  vpColVector _W1 = vpColVector::sort(W1);
145 
146  vpColVector diff = _W0-_W1;
147  double error=-1.0;
148 
149  for(unsigned int i=0;i<6;i++)
150  error=std::max(abs(diff[i]),error);
151 
152  return error<epsilon;
153 
154 }
155 
156 #endif
157 
158 bool testSvdOpenCvGSLCoherence(double epsilon)
159 {
160 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101) && defined (VISP_HAVE_GSL) // Require opencv >= 2.1.1
161  vpMatrix A;
162  vpMatrix vA;
163  vpColVector wA;
164  vpMatrix B;
165  vpMatrix vB;
166  vpColVector wB;
167  A.resize(6,6);
168  B.resize(6,6);
169  vA.resize(6,6);
170  vB.resize(6,6);
171  wA.resize(6);
172  wB.resize(6);
173 
174  for (unsigned int i=0 ; i < A.getRows() ; i++)
175  for (unsigned int j=0 ; j < A.getCols() ; j++)
176  B[i][j] = A[i][j] = (double)rand()/(double)RAND_MAX;
177 
178  A.svdOpenCV(wA,vA);
179  B.svdGsl(wB,vB);
180 
181  bool error=false;
182  for (unsigned int i=0 ; i < A.getRows() ; i++){
183  error = error | (abs(wA[i]-wB[i])>epsilon);
184  }
185 
186  return !error;
187 #else
188  (void)epsilon;
189  return true;
190 #endif
191 }
192 
193 int
194 main(int argc, const char ** argv)
195 {
196  try {
197  // Read the command line options
198  if (getOptions(argc, argv) == false) {
199  exit (-1);
200  }
201 
202  vpMatrix L(60000,6), Ls ;
203  for (unsigned int i=0 ; i < L.getRows() ; i++)
204  for (unsigned int j=0 ; j < L.getCols() ; j++)
205  L[i][j] = 2*i+j + cos((double)(i+j))+((double)(i)) ;
206  // std::cout << L << std::endl ;
207  Ls = L ;
208  std::cout << "--------------------------------------"<<std::endl ;
209 
210  vpColVector W(L.getCols()) ;
211  vpMatrix V(L.getCols(), L.getCols()) ;
212 
213  double t = vpTime::measureTimeMs() ;
214  L.svdNr(W,V) ;
215  t = vpTime::measureTimeMs() -t ;
216 
217  std::cout <<"svdNr Numerical recipes \n time " <<t << std::endl;
218  std::cout << W.t() ;
219  std::cout << "--------------------------------------"<<std::endl ;
220 
221 
222 #ifdef VISP_HAVE_GSL
223  L = Ls ;
224  t = vpTime::measureTimeMs() ;
225  L.svdGsl(W,V) ;
226  t = vpTime::measureTimeMs() -t ;
227  std::cout <<"svdGsl_mod \n time " <<t << std::endl;
228  std::cout << W.t() ;
229 
230  std::cout << "--------------------------------------"<<std::endl ;
231  std::cout << "TESTING RANDOM MATRICES:" ;
232 
233  bool ret = true;
234  for(unsigned int i=0;i<2000;i++)
235  ret = ret & testRandom(0.00001);
236  if(ret)
237  std:: cout << "Success"<< std:: endl;
238  else
239  std:: cout << "Fail"<< std:: endl;
240 
241  std::cout << "--------------------------------------"<<std::endl ;
242 #endif
243 
244  std::cout << "--------------------------------------"<<std::endl ;
245  std::cout << "TESTING OPENCV-GSL coherence:" ;
246 
247  bool ret2 = true;
248  for(unsigned int i=0;i<1;i++)
249  ret2 = ret2 & testSvdOpenCvGSLCoherence(0.00001);
250  if(ret2)
251  std:: cout << "Success"<< std:: endl;
252  else
253  std:: cout << "Fail"<< std:: endl;
254 
255  std::cout << "--------------------------------------"<<std::endl ;
256 
257  L = Ls ;
258  t = vpTime::measureTimeMs() ;
259  L.svdFlake(W,V) ;
260  t = vpTime::measureTimeMs() -t ;
261  std::cout <<"svdFlake\n time " <<t << std::endl;
262  std::cout << W.t() ;
263  return 0;
264  }
265  catch(vpException e) {
266  std::cout << "Catch an exception: " << e << std::endl;
267  return 1;
268  }
269 }
270 
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
Definition: vpMatrix.cpp:183
static vpColVector sort(const vpColVector &v)
sort the elements of vector v
error that can be emited by ViSP classes.
Definition: vpException.h:76
static double measureTimeMs()
Definition: vpTime.cpp:86
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:79
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
unsigned int getCols() const
Return the number of columns of the matrix.
Definition: vpMatrix.h:163
unsigned int getRows() const
Return the number of rows of the matrix.
Definition: vpMatrix.h:161
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:94