![]() |
last update 20 Sep 2009 |
![]() |
00001 /* 00002 * Copyright (C) 2008 00003 * Pablo Alvarado 00004 * 00005 * This file is part of the Computer Vision and Robotics Library (CVR-Lib ) 00006 * 00007 * The CVR-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the BSD License. 00009 * 00010 * All rights reserved. 00011 * 00012 * Redistribution and use in source and binary forms, with or without 00013 * modification, are permitted provided that the following conditions are met: 00014 * 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 00018 * 2. Redistributions in binary form must reproduce the above copyright notice, 00019 * this list of conditions and the following disclaimer in the documentation 00020 * and/or other materials provided with the distribution. 00021 * 00022 * 3. Neither the name of the authors nor the names of its contributors may be 00023 * used to endorse or promote products derived from this software without 00024 * specific prior written permission. 00025 * 00026 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00027 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00029 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00030 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00031 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00032 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00033 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00034 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00035 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00036 * POSSIBILITY OF SUCH DAMAGE. 00037 */ 00038 00039 /** 00040 * \file cvrLinearLeastSquares.h 00041 * Contains the class cvr::linearLeastSquares, 00042 * to solve a least squares linear problem. 00043 * 00044 * \author Pablo Alvarado 00045 * \date 16.01.2008 00046 * 00047 * revisions ..: $Id: cvrLinearLeastSquares.h,v $ 00048 */ 00049 00050 #ifndef _CVR_LINEAR_LEAST_SQUARES_H_ 00051 #define _CVR_LINEAR_LEAST_SQUARES_H_ 00052 00053 #include "cvrMatrix.h" 00054 #include "cvrVector.h" 00055 #include "cvrLinearAlgebraFunctor.h" 00056 00057 #ifdef HAVE_LAPACK 00058 #include "cvrLapackInterface.h" 00059 #endif 00060 00061 00062 namespace cvr { 00063 00064 /** 00065 * Class linearLeastSquares 00066 * 00067 * Solving the linear least squares problem means to find a solution \f$x\f$ 00068 * for 00069 * \f[ 00070 * A x = b 00071 * \f] 00072 * by minimizing the Euclidean norm squared of the residual \f$Ax-b\f$. 00073 * Here \f$A\f$ is a m x n matrix, with m>n, \f$x\f$ is an n-dimensional 00074 * vector, and \f$b\f$ is a m-dimensional vector. 00075 * 00076 * This class is usually used to solve an over-determined system of linear 00077 * equations, where there is more equations than variables. If the LAPACK 00078 * library is used, this method can also be employed to solve 00079 * under-determined system, choosing the solution of minimal norm. 00080 * 00081 * If LAPACK is enabled, the functor provides several algorithms for the same 00082 * task, which vary in speed and robustness against the ill-conditionness of 00083 * the matrix A. Please refer to the LAPACK documentation for more details: 00084 * 00085 * - QR: uses the QR (or LQ) decomposition of the matrix A. 00086 * This method can be employed if and only if the matrix A has full rank. 00087 * - CompleteFactorization: performs a complete orthogonal factorization 00088 * - SVD: uses a singular value decomposition. This is the recomended method 00089 * if the matrix A is ill-conditioned, and the only one used if LAPACK 00090 * is not found. 00091 * - DCSVD: uses a divide-and-conquer singular value decomposition. 00092 * 00093 * @see linearLeastSquares::parameters. 00094 * 00095 * @ingroup gLinearAlgebra 00096 */ 00097 class linearLeastSquares : public linearAlgebraFunctor { 00098 public: 00099 /** 00100 * Enumeration for the algorithms available 00101 */ 00102 enum eAlgorithm { 00103 QR, /**< QR decomposition: slower but more robust */ 00104 CompleteFactorization, /**< Complete Orthogonal Factorization */ 00105 SVD, /**< Singular Value Decomposition: slowest but works even with 00106 ill-conditioned matrices */ 00107 DCSVD /**< Divide-and-conquer singular value decomposition */ 00108 }; 00109 00110 /** 00111 * The parameters for the class linearLeastSquares 00112 */ 00113 class parameters : public linearAlgebraFunctor::parameters { 00114 public: 00115 /** 00116 * Default constructor 00117 */ 00118 parameters(); 00119 00120 /** 00121 * Copy constructor 00122 * @param other the parameters object to be copied 00123 */ 00124 parameters(const parameters& other); 00125 00126 /** 00127 * Destructor 00128 */ 00129 ~parameters(); 00130 00131 /** 00132 * Copy the contents of a parameters object 00133 * @param other the parameters object to be copied 00134 * @return a reference to this parameters object 00135 */ 00136 parameters& copy(const parameters& other); 00137 00138 /** 00139 * Copy the contents of a parameters object 00140 * @param other the parameters object to be copied 00141 * @return a reference to this parameters object 00142 */ 00143 parameters& operator=(const parameters& other); 00144 00145 /** 00146 * Returns the complete name of the parameters class. 00147 */ 00148 virtual const std::string& name() const; 00149 00150 /** 00151 * Returns a pointer to a clone of the parameters. 00152 */ 00153 virtual parameters* clone() const; 00154 00155 /** 00156 * Returns a pointer to a new instance of the parameters. 00157 */ 00158 virtual parameters* newInstance() const; 00159 00160 /** 00161 * Write the parameters in the given ioHandler 00162 * @param handler the ioHandler to be used 00163 * @param complete if true (the default) the enclosing begin/end will 00164 * be also written, otherwise only the data block will be written. 00165 * @return true if write was successful 00166 */ 00167 virtual bool write(ioHandler& handler,const bool complete=true) const; 00168 00169 /** 00170 * Read the parameters from the given ioHandler 00171 * @param handler the ioHandler to be used 00172 * @param complete if true (the default) the enclosing begin/end will 00173 * be also written, otherwise only the data block will be written. 00174 * @return true if write was successful 00175 */ 00176 virtual bool read(ioHandler& handler,const bool complete=true); 00177 00178 // ------------------------------------------------ 00179 // the parameters 00180 // ------------------------------------------------ 00181 00182 /** 00183 * Which algorithm should be used to solve the least squares problem. 00184 * 00185 * The available methods are: 00186 * - QR: uses the QR (or LQ) decomposition of the matrix A. 00187 * This method can be employed if and only if the matrix A has full 00188 * rank. 00189 * - CompleteFactorization: performs a complete orthogonal factorization 00190 * - SVD: uses a singular value decomposition. This is the recomended 00191 * method if the matrix A is ill-conditioned, and the only one 00192 * used if LAPACK is not found. 00193 * - DCSVD: uses a divide-and-conquer singular value decomposition. 00194 * 00195 * Default value: SVD 00196 */ 00197 eAlgorithm algorithm; 00198 00199 /** 00200 * The \c rCondition is used to determine the effective rank of the 00201 * matrix A, which is defined as the order of the largest leading 00202 * triangular submatrix R11 in the QR factorization with pivoting of A, 00203 * whose estimated condition number is less than 1.0/rCondition 00204 * 00205 * For intance, all singular values less than or equal to this value 00206 * multiplied by the largest singular value are set to zero. 00207 * 00208 * Default value: 0.0 00209 */ 00210 double rCondition; 00211 }; 00212 00213 /** 00214 * Default constructor 00215 */ 00216 linearLeastSquares(); 00217 00218 /** 00219 * Construct a functor using the given parameters 00220 */ 00221 linearLeastSquares(const parameters& par); 00222 00223 /** 00224 * Copy constructor 00225 * @param other the object to be copied 00226 */ 00227 linearLeastSquares(const linearLeastSquares& other); 00228 00229 /** 00230 * Destructor 00231 */ 00232 virtual ~linearLeastSquares(); 00233 00234 /** 00235 * Find the solution \f$x\f$ for 00236 * \f[ 00237 * A x = b 00238 * \f] 00239 * 00240 * @param A matrix A 00241 * @param b vector b 00242 * @param x vector x where the solution is stored. 00243 * 00244 * The dimension of \c b and the number of rows of A must be identical. 00245 * The resulting dimension of \c x will be identical to the number of 00246 * columns of A. 00247 * 00248 * The internal state of the class will store the decomposition of the 00249 * matrix A, so that the other apply methods with other \c b vectors can 00250 * be used. 00251 * 00252 * @return true if apply successful or false otherwise. 00253 */ 00254 bool apply(const fmatrix& A, 00255 const fvector& b, 00256 fvector& x) const; 00257 00258 /** 00259 * Find the solution \f$x\f$ for 00260 * \f[ 00261 * A x = b 00262 * \f] 00263 * 00264 * @param A matrix A 00265 * @param b vector b 00266 * @param x vector x where the solution is stored. 00267 * 00268 * The dimension of \c b and the number of rows of A must be identical. 00269 * The resulting dimension of \c x will be identical to the number of 00270 * columns of A. 00271 * 00272 * The internal state of the class will store the decomposition of the 00273 * matrix A, so that the other apply methods with other \c b vectors can 00274 * be used. 00275 * 00276 * @return true if apply successful or false otherwise. 00277 */ 00278 bool apply(const dmatrix& A, 00279 const dvector& b, 00280 dvector& x) const; 00281 00282 00283 /** 00284 * Find the solution \f$x\f$ for 00285 * \f[ 00286 * A x = b 00287 * \f] 00288 * 00289 * @param A matrix A 00290 * @param b each column is a vector b 00291 * @param x each column is a vector x where the solution is stored for 00292 * the corresponding column in b. 00293 * 00294 * The dimension of \c b and the number of rows of A must be identical. 00295 * The resulting dimension of \c x will be identical to the number of 00296 * columns of A. 00297 * 00298 * The internal state of the class will store the decomposition of the 00299 * matrix A, so that the other apply methods with other \c b vectors can 00300 * be used. 00301 * 00302 * @return true if apply successful or false otherwise. 00303 */ 00304 bool apply(const fmatrix& A, 00305 const fmatrix& b, 00306 fmatrix& x) const; 00307 00308 /** 00309 * Find the solution \f$x\f$ for 00310 * \f[ 00311 * A x = b 00312 * \f] 00313 * 00314 * @param A matrix A 00315 * @param b each column is a vector b 00316 * @param x each column is a vector x where the solution is stored for 00317 * the corresponding column in b. 00318 * 00319 * The dimension of \c b and the number of rows of A must be identical. 00320 * The resulting dimension of \c x will be identical to the number of 00321 * columns of A. 00322 * 00323 * The internal state of the class will store the decomposition of the 00324 * matrix A, so that the other apply methods with other \c b vectors can 00325 * be used. 00326 * 00327 * @return true if apply successful or false otherwise. 00328 */ 00329 bool apply(const dmatrix& A, 00330 const dmatrix& b, 00331 dmatrix& x) const; 00332 00333 /** 00334 * Copy data of "other" functor. 00335 * @param other the functor to be copied 00336 * @return a reference to this functor object 00337 */ 00338 linearLeastSquares& copy(const linearLeastSquares& other); 00339 00340 /** 00341 * Alias for copy member 00342 * @param other the functor to be copied 00343 * @return a reference to this functor object 00344 */ 00345 linearLeastSquares& operator=(const linearLeastSquares& other); 00346 00347 /** 00348 * Returns the complete name of the functor class 00349 */ 00350 virtual const std::string& name() const; 00351 00352 /** 00353 * Returns a pointer to a clone of this functor. 00354 */ 00355 virtual linearLeastSquares* clone() const; 00356 00357 /** 00358 * Returns a pointer to a new instance of this functor. 00359 */ 00360 virtual linearLeastSquares* newInstance() const; 00361 00362 /** 00363 * Returns used parameters 00364 */ 00365 const parameters& getParameters() const; 00366 00367 private: 00368 /** 00369 * 00370 */ 00371 template<typename T> 00372 class helper 00373 #ifdef HAVE_LAPACK 00374 : public lapackInterface 00375 #endif 00376 { 00377 public: 00378 /** 00379 * Find the solution \f$x\f$ for 00380 * \f[ 00381 * A x = b 00382 * \f] 00383 * 00384 * where the matrix A was given in a previous apply or by means of the 00385 * use() methods. 00386 * 00387 * @param b vector b 00388 * @param x vector x where the solution is stored. 00389 * 00390 * The dimension of \c b and the number of rows of A must be identical. 00391 * The resulting dimension of \c x will be identical to the number of 00392 * columns of A. 00393 * 00394 * @return true if apply successful or false otherwise. 00395 */ 00396 bool solve(const parameters& pars, 00397 const matrix<T>& A, 00398 const vector<T>& b, 00399 vector<T>& x) const; 00400 00401 /** 00402 * Find the solution \f$x\f$ for 00403 * \f[ 00404 * A x = b 00405 * \f] 00406 * 00407 * where the matrix A was given in a previous apply or by means of the 00408 * use() methods. 00409 * 00410 * @param b vector b 00411 * @param x vector x where the solution is stored. 00412 * 00413 * The dimension of \c b and the number of rows of A must be identical. 00414 * The resulting dimension of \c x will be identical to the number of 00415 * columns of A. 00416 * 00417 * @return true if apply successful or false otherwise. 00418 */ 00419 bool solve(const parameters& pars, 00420 const matrix<T>& A, 00421 const matrix<T>& b, 00422 matrix<T>& x) const; 00423 00424 protected: 00425 #ifdef HAVE_LAPACK 00426 00427 /** 00428 * GELS - solve overdetermined or underdetermined real linear systems 00429 * involving an M-by-N matrix A, or its transpose, using a QR or LQ 00430 * factorization of A }; 00431 */ 00432 int gels(char *trans, integer *m, integer *n, integer *nrhs, T* a, 00433 integer *lda, T* b, integer* ldb, T* work, 00434 integer *lwork, integer *info) const; 00435 /** 00436 * SGELSY - compute the minimum-norm solution to a real linear least 00437 * squares problem. 00438 * 00439 * Does the complete orthogonal decomposition 00440 */ 00441 int gelsy(integer *m, integer *n, integer *nrhs, T* a, 00442 integer *lda, T* b, integer *ldb, integer *jpvt, 00443 T* rcond,integer *rank, T* work, integer *lwork, 00444 integer *info) const; 00445 00446 /** 00447 * SGELSS - compute the minimum norm solution to a real linear 00448 * least squares problem using SVD 00449 */ 00450 int gelss(integer *m, integer *n, integer *nrhs, T* a, 00451 integer *lda, T* b, integer *ldb, T* s, T* rcond, 00452 integer *rank, T* work, integer *lwork, integer *info) const; 00453 00454 /** 00455 * SGELSD - compute the minimum-norm solution to a real linear least 00456 * squares problem. Uses the divide and conquer SVD method. 00457 */ 00458 int gelsd(integer *m, integer *n, integer *nrhs, T *a, 00459 integer *lda, T *b, integer *ldb, T *s, T *rcond, 00460 integer *rank, T *work, integer *lwork, integer *iwork, 00461 integer *info) const; 00462 #endif 00463 }; 00464 00465 /** 00466 * Helper class for float methods. 00467 */ 00468 helper<float> fhelper_; 00469 00470 /** 00471 * Helper class for double methods. 00472 */ 00473 helper<double> dhelper_; 00474 }; 00475 00476 /** 00477 * Read a linearLeastSquares::eAlgorithm 00478 * 00479 * @ingroup gStorable 00480 */ 00481 bool read(ioHandler& handler, 00482 linearLeastSquares::eAlgorithm& data); 00483 00484 /** 00485 * Write a linearLeastSquares::eAlgorithm 00486 * 00487 * @ingroup gStorable 00488 */ 00489 bool write(ioHandler& handler, 00490 const linearLeastSquares::eAlgorithm& data); 00491 00492 } 00493 00494 #endif 00495