LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiMatrixInversion.h

00001 /*
00002  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 /*----------------------------------------------------------------
00024  * project ....: LTI Digital Image/Signal Processing Library
00025  * file .......: ltiMatrixInversion.h
00026  * authors ....: Jochen Wickel
00027  * organization: LTI, RWTH Aachen
00028  * creation ...: 07.10.01
00029  * revisions ..: $Id: ltiMatrixInversion.h,v 1.10 2006/02/08 12:35:26 ltilib Exp $
00030  */
00031 
00032 
00033 #ifndef _LTI_MATRIX_INVERSION_H_
00034 #define _LTI_MATRIX_INVERSION_H_
00035 
00036 #include "ltiLinearAlgebraFunctor.h"
00037 
00038 namespace lti {
00039   /**
00040    * Matrix inversion functor.
00041    *
00042    * Computes the inverse of a matrix using LU decomposition.
00043    * Only use this functor if the inverse of a matrix is needed explicity!
00044    * To solve an equation system
00045    * Ax=b or a set of equation systems AX=B it is more efficient to use the
00046    * LU solution method (solve Ax=b resp. AX[i]=B[i]) directly than
00047    * inverting A and multiplying the result by b resp. B!
00048    *
00049    * If the parameter value method is set to SVD, a singular value
00050    * decomposition is used to invert the matrix, instead of the LU
00051    * decomposition method.
00052    *
00053    * The apply() methods return false if the matrix is singular or
00054    * close to being singular. This is defined by checking that the
00055    * smalles singular value is greater than
00056    * std::numeric_limits<T>::epsilon() for SVD and internally in the
00057    * LU decomposition.
00058    *
00059    * For small (2x2,3x3 or 4x4) symmetric matrices you can also use
00060    * lti::symmetricMatrixInversion.
00061    *
00062    * @ingroup gLinearAlgebra
00063    */
00064   template <class T>
00065   class matrixInversion : public linearAlgebraFunctor {
00066   public:
00067     /**
00068      * %parameters class for lti::matrixInversion %functor
00069      */
00070     class parameters: public linearAlgebraFunctor::parameters {
00071 
00072     public:
00073       /**
00074        * Default constructor
00075        */
00076       parameters(void) : linearAlgebraFunctor::parameters() {
00077         method=LUD;
00078       };
00079 
00080       /**
00081        * copy constructor
00082        * @param other the parameters object to be copied
00083        */
00084       parameters(const parameters& other) 
00085         : linearAlgebraFunctor::parameters() {
00086         copy(other);
00087       };
00088 
00089       /**
00090        * destructor
00091        */
00092       ~parameters() {};
00093 
00094       /**
00095        * returns name of this type
00096        */
00097       const char* getTypeName() const {
00098         return "matrixInversion::parameters";
00099       };
00100 
00101       /**
00102        * copy member
00103        *
00104        * @param other the parameters object to be copied
00105        * @return a reference to this object
00106        */
00107       parameters& copy(const parameters& other) {
00108 #       ifndef _LTI_MSC_6
00109           // MS Visual C++ 6 is not able to compile this...
00110           linearAlgebraFunctor::parameters::copy(other);
00111 #       else
00112           // ...so we have to use this workaround.
00113           // Conditional on that, copy may not be virtual.
00114           functor::parameters&
00115             (functor::parameters::* p_copy)
00116             (const functor::parameters&) =
00117             functor::parameters::copy;
00118           (this->*p_copy)(other);
00119 #       endif
00120 
00121         method=other.method;
00122 
00123         return *this;
00124       };
00125 
00126       /**
00127        * return a cloned instance of this one.
00128        */
00129       virtual functor::parameters* clone() const {
00130         return new parameters(*this);
00131       };
00132 
00133         /**
00134          * write the parameters in the given ioHandler
00135          * @param handler the ioHandler to be used
00136          * @param complete if true (the default) the enclosing begin/end will
00137          *        be also written, otherwise only the data block will be
00138          *        written.
00139          * @return true if write was successful
00140          */
00141 #     ifndef _LTI_MSC_6
00142         virtual bool write(ioHandler& handler,const bool complete=true) const
00143 #     else
00144         bool writeMS(ioHandler& handler,const bool complete=true) const
00145 #     endif
00146         {
00147           bool b = true;
00148           if (complete) {
00149             b = handler.writeBegin();
00150           }
00151 
00152           if (b) {
00153             if (method == LUD) {
00154               lti::write(handler,"method","LUD");
00155             } else {
00156               lti::write(handler,"method","SVD");
00157             }
00158           }
00159 
00160 #       ifndef _LTI_MSC_6
00161           // This is the standard C++ code, which MS Visual C++ 6 is not
00162           // able to compile...
00163           b = b && linearAlgebraFunctor::parameters::write(handler,false);
00164 #       else
00165           bool (functor::parameters::* p_writeMS)(ioHandler&,
00166                                                   const bool) const =
00167             functor::parameters::writeMS;
00168           b = b && (this->*p_writeMS)(handler,false);
00169 #       endif
00170 
00171           if (complete) {
00172             b = b && handler.writeEnd();
00173           }
00174 
00175           return b;
00176         }
00177 
00178 #     ifdef _LTI_MSC_6
00179         virtual bool write(ioHandler& handler,
00180                            const bool complete = true) const {
00181            // ...we need this workaround to cope with another really
00182            // awful MSVC bug.
00183            return writeMS(handler,complete);
00184         }
00185 #     endif
00186 
00187         /**
00188          * read the parameters from the given ioHandler
00189          * @param handler the ioHandler to be used
00190          * @param complete if true (the default) the enclosing begin/end will
00191          *        be also read, otherwise only the data block will be read.
00192          * @return true if write was successful
00193          */
00194 #     ifndef _LTI_MSC_6
00195         virtual bool read(ioHandler& handler,const bool complete = true)
00196 #     else
00197         bool readMS(ioHandler& handler,const bool complete=true)
00198 #     endif
00199         {
00200           bool b = true;
00201           if (complete) {
00202             b = handler.readBegin();
00203           }
00204 
00205           if (b) {
00206             std::string str;
00207             lti::read(handler,"method",str);
00208             if (str == "LUD") {
00209               method = LUD;
00210             } else {
00211               method = SVD;
00212             }
00213           }
00214 
00215 #     ifndef _LTI_MSC_6
00216           // This is the standard C++ code, which MS Visual C++ 6 is not
00217           // able to compile...
00218           b = b && linearAlgebraFunctor::parameters::read(handler,false);
00219 #     else
00220           bool (functor::parameters::* p_readMS)(ioHandler&,const bool) =
00221           functor::parameters::readMS;
00222           b = b && (this->*p_readMS)(handler,false);
00223 #     endif
00224 
00225           if (complete) {
00226             b = b && handler.readEnd();
00227           }
00228 
00229           return b;
00230         }
00231 
00232 #     ifdef _LTI_MSC_6
00233         virtual bool read(ioHandler& handler,const bool complete=true) {
00234           // ...we need this workaround to cope with another really awful MSVC
00235           // bug.
00236           return readMS(handler,complete);
00237         }
00238 #      endif
00239 
00240       // ------------------------------------------------------------------
00241       // The Parameters
00242       // ------------------------------------------------------------------
00243 
00244       /**
00245        * Available algorithms for matrix inversion
00246        */
00247       enum algorithmType {
00248         LUD = 0, //!< LU-Decomposition
00249         SVD = 1  //!< Singular Value Decomposition
00250       };
00251 
00252       /**
00253        * Algorithm to be used in the matrix inversion
00254        *
00255        * Default value: LUD
00256        */
00257       algorithmType method;
00258     };
00259 
00260     /**
00261      * default constructor
00262      */
00263     matrixInversion();
00264 
00265     /**
00266      * destructor
00267      */
00268     virtual ~matrixInversion() {};
00269 
00270     /**
00271      * onCopy version of apply.
00272      *
00273      * @param theMatrix matrix to be inverted
00274      * @param theInverse inverted matrix
00275      * @return true if inversion was possible, false otherwise.
00276      */
00277     bool apply(const matrix<T>& theMatrix,
00278                      matrix<T>& theInverse) const;
00279 
00280     /**
00281      * onPlace version of apply.
00282      *
00283      * @param theMatrix matrix to be inverted.  The result will be left here
00284      *                  too.
00285      * @return true if inversion was possible, false otherwise.
00286      */
00287     bool apply(matrix<T>& theMatrix) const;
00288 
00289     /**
00290      * returns a pointer to a clone of the functor.
00291      */
00292     virtual functor* clone() const {
00293       return (new matrixInversion<T>(*this));
00294     };
00295 
00296     /**
00297      * change the used parameters in order to used the
00298      * LU-decomposition method for matrix inversion.
00299      */
00300     void useLUD();
00301 
00302     /**
00303      * change the used parameters in order to used the singular value
00304      * decomposition method for matrix inversion.
00305      */
00306     void useSVD();
00307 
00308     /**
00309      * returns the name of this type
00310      */
00311     virtual const char* getTypeName() const {return "matrixInversion";};
00312 
00313     /**
00314      * get a constant reference to the actual used parameters.
00315      */
00316     const parameters& getParameters() const;
00317 
00318   protected:
00319     /**
00320      * smallest value of type T, which can be added to 0 in order to produce
00321      * a number different than zero.
00322      */
00323     static const T my_epsilon;
00324   };
00325 }
00326 
00327 #endif

Generated on Sat Apr 10 15:25:50 2010 for LTI-Lib by Doxygen 1.6.1