CVR-Lib last update 20 Sep 2009

cvrLinearLeastSquares.h

Go to the documentation of this file.
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 

Generated on Sun Sep 20 22:07:59 2009 for CVR-Lib by Doxygen 1.5.8