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

ltiBackSubstitution.h

00001 /*
00002  * Copyright (C) 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 /*--------------------------------------------------------------------
00025  * project ....: LTI-Lib: Image Processing and Computer Vision Library
00026  * file .......: ltiBackSubstitution.h
00027  * authors ....: Peter Doerfler
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 20.5.2003
00030  * revisions ..: $Id: ltiBackSubstitution.h,v 1.10 2006/02/08 12:12:17 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_BACK_SUBSTITUTION_H_
00034 #define _LTI_BACK_SUBSTITUTION_H_
00035 
00036 #include "ltiLinearAlgebraFunctor.h"
00037 #include "ltiVector.h"
00038 #include "ltiMatrix.h"
00039 #include "ltiTriangularMatrixType.h"
00040 
00041 namespace lti {
00042   /**
00043    * Backsubstitution. Let \a L be a lower triangular matrix and
00044    * \a U an upper triangular matrix. Backsubstitution solves the
00045    * following linear equation systems for \a x:
00046    *
00047    * U*x=b or x*L=b
00048    *
00049    * In the first case, \a x and \a b are column vectors, in the latter
00050    * case they are row vectors. The data %matrix can be given to
00051    * the functor via the parameters or directly in the apply
00052    * methods. There are also apply methods that calculate the
00053    * backsubstitution for multiple right-sides \a b. The vectors are
00054    * treated as before, ie they are in columns for the first case and
00055    * in rows for the second.
00056    *
00057    * \b Note that the column vector matrix will be transposed twice
00058    * and thus takes longer to compute, try to use the vector-apply
00059    * instead.
00060    *
00061    * @see lti::backSubstitution
00062    */
00063   template<class T>
00064   class backSubstitution : public linearAlgebraFunctor {
00065   public:
00066     /**
00067      * the parameters for the class backSubstitution
00068      */
00069     class parameters 
00070       : public linearAlgebraFunctor::parameters, 
00071         virtual public triangularMatrixType {
00072     public:
00073 
00074       /**
00075        * default constructor. The triangularType is Upper by default.
00076        */
00077       parameters() : linearAlgebraFunctor::parameters(), theMatrix() {
00078         //TODO: Initialize your parameter values!
00079         // If you add more parameters manually, do not forget to do following:
00080         // 1. indicate in the default constructor the default values
00081         // 2. make sure that the copy member also copy your new parameters
00082         // 3. make sure that the read and write members also read and
00083         //    write your parameters
00084         
00085         triangularType = Upper;
00086       };
00087 
00088       /**
00089        * copy constructor
00090        * @param other the parameters object to be copied
00091        */
00092       parameters(const parameters& other) : linearAlgebraFunctor::parameters() {
00093         copy(other);
00094       }
00095       
00096       /**
00097        * destructor
00098        */
00099       ~parameters() {
00100       };
00101 
00102       /**
00103        * returns name of this type
00104        */
00105       const char* getTypeName() const {
00106         return "backSubstitution::parameters";
00107       };
00108 
00109       /**
00110        * copy the contents of a parameters object
00111        * @param other the parameters object to be copied
00112        * @return a reference to this parameters object
00113        */
00114       parameters& copy(const parameters& other) {
00115 #     ifndef _LTI_MSC_6
00116         // MS Visual C++ 6 is not able to compile this...
00117         linearAlgebraFunctor::parameters::copy(other);
00118 #     else
00119         // ...so we have to use this workaround.
00120         // Conditional on that, copy may not be virtual.
00121         functor::parameters& (functor::parameters::* p_copy)
00122                             (const functor::parameters&) =
00123                             functor::parameters::copy;
00124         (this->*p_copy)(other);
00125 #     endif
00126         triangularMatrixType::copy(other);
00127         
00128         theMatrix.copy(other.theMatrix);
00129         
00130         return *this;
00131       };
00132 
00133       /**
00134        * copy the contents of a parameters object
00135        * @param other the parameters object to be copied
00136        * @return a reference to this parameters object
00137        */
00138       parameters& operator=(const parameters& other) {
00139         return copy(other);
00140       };
00141 
00142       /**
00143        * returns a pointer to a clone of the parameters
00144        */
00145       virtual functor::parameters* clone() const {
00146         return new parameters(*this);
00147       };
00148 
00149 #     ifndef _LTI_MSC_6
00150       /**
00151        * write the parameters in the given ioHandler
00152        * @param handler the ioHandler to be used
00153        * @param complete if true (the default) the enclosing begin/end will
00154        *        be also written, otherwise only the data block will be written.
00155        * @return true if write was successful
00156        */
00157       virtual bool write(ioHandler& handler,const bool complete=true) const
00158 #     else
00159       /**
00160        * this function is required by MSVC only, as a workaround for a
00161        * very awful bug, which exists since MSVC V.4.0, and still by
00162        * V.6.0 with all bugfixes (so called "service packs") remains
00163        * there...  This method is also public due to another bug, so please
00164        * NEVER EVER call this method directly: use write() instead
00165        */
00166       bool writeMS(ioHandler& handler,const bool complete=true) const
00167 #     endif
00168       {
00169         bool b = true;
00170         if (complete) {
00171           b = handler.writeBegin();
00172         }
00173         
00174         if (b) {
00175           
00176           lti::write(handler,"theMatrix", theMatrix);
00177 
00178         }
00179 
00180 #     ifndef _LTI_MSC_6
00181         // This is the standard C++ code, which MS Visual C++ 6 is not able to
00182         // compile...
00183         b = b && linearAlgebraFunctor::parameters::write(handler,false);
00184 #     else
00185         bool (linearAlgebraFunctor::parameters::* p_writeMS)(ioHandler&,
00186                                                          const bool) const =
00187           linearAlgebraFunctor::parameters::writeMS;
00188         b = b && (this->*p_writeMS)(handler,false);
00189 #     endif
00190         b = b && triangularMatrixType::write(handler,false);
00191 
00192         if (complete) {
00193           b = b && handler.writeEnd();
00194         }
00195 
00196         return b;
00197       }
00198 
00199 #     ifdef _LTI_MSC_6
00200       /**
00201        * write the parameters in the given ioHandler
00202        * @param handler the ioHandler to be used
00203        * @param complete if true (the default) the enclosing begin/end will
00204        *        be also written, otherwise only the data block will be written.
00205        * @return true if write was successful
00206        */
00207       bool write(ioHandler& handler,
00208                  const bool complete=true) const {
00209         // ...we need this workaround to cope with another really
00210         // awful MSVC bug.
00211         return writeMS(handler,complete);
00212       }
00213 #     endif
00214 
00215 
00216 #     ifndef _LTI_MSC_6
00217       /**
00218        * read the parameters from the given ioHandler
00219        * @param handler the ioHandler to be used
00220        * @param complete if true (the default) the enclosing begin/end will
00221        *        be also written, otherwise only the data block will be written.
00222        * @return true if write was successful
00223        */
00224       virtual bool read(ioHandler& handler,const bool complete=true)
00225 #     else
00226       /**
00227        * this function is required by MSVC only, as a workaround for a
00228        * very awful bug, which exists since MSVC V.4.0, and still by
00229        * V.6.0 with all bugfixes (so called "service packs") remains
00230        * there...  This method is also public due to another bug, so please
00231        * NEVER EVER call this method directly: use read() instead
00232        */
00233       bool readMS(ioHandler& handler,const bool complete=true)
00234 #     endif
00235       {
00236         bool b = true;
00237         if (complete) {
00238           b = handler.readBegin();
00239         }
00240         
00241         if (b) {
00242 
00243           lti::read(handler,"theMatrix", theMatrix);
00244         }
00245 
00246 #       ifndef _LTI_MSC_6
00247         // This is the standard C++ code, which MS Visual C++ 6 is not
00248         // able to compile...
00249         b = b && linearAlgebraFunctor::parameters::read(handler,false);
00250 #       else
00251         bool (linearAlgebraFunctor::parameters::* p_readMS)(ioHandler&,
00252                                                         const bool) =
00253           linearAlgebraFunctor::parameters::readMS;
00254         b = b && (this->*p_readMS)(handler,false);
00255 #       endif
00256         b = b && triangularMatrixType::read(handler,false);
00257 
00258         if (complete) {
00259           b = b && handler.readEnd();
00260         }
00261         
00262         return b;
00263       }
00264 
00265 #     ifdef _LTI_MSC_6
00266       /**
00267        * read the parameters from the given ioHandler
00268        * @param handler the ioHandler to be used
00269        * @param complete if true (the default) the enclosing begin/end will
00270        *        be also written, otherwise only the data block will be written.
00271        * @return true if write was successful
00272        */
00273       bool read(ioHandler& handler,const bool complete=true) {
00274         // ...we need this workaround to cope with another really awful MSVC
00275         // bug.
00276         return readMS(handler,complete);
00277       }
00278 #     endif
00279 
00280       // ------------------------------------------------
00281       // the parameters
00282       // ------------------------------------------------
00283 
00284 
00285       /**
00286        * The data matrix.
00287        */
00288       matrix<T> theMatrix;
00289 
00290     };
00291 
00292     /**
00293      * default constructor
00294      */
00295     backSubstitution();
00296 
00297     /**
00298      * constructor, sets the data matrix and its triangular type in
00299      * the parameters.
00300      *
00301      * \b Note: Using this constructor, the data matrix is copied
00302      * twice (Once to internally put it into a parameters object and
00303      * then when setting the parameters). It can be better to let
00304      * parameters::theMatrix use the data of some matrix you have:
00305      *
00306      * \code
00307      * matrix<double> myData; //let this contain the data
00308      * backSubstitution<double>::parameters param;
00309      * param.theMatrix.useExternData(myData.rows(),myData.columns(),&myData.at(0,0))
00310      * backSubstitution<double> mySubst(param);
00311      * \endcode
00312      *
00313      * The fastest method is to use one of the apply-methods where the
00314      * data matrix is an argument.
00315      *
00316      * @param theMatrix the data matrix
00317      * @param tType triangularType of \a theMatrix
00318      */
00319     backSubstitution(const matrix<T>& theMatrix, 
00320                      const typename parameters::eTriangularType& tType=
00321                      parameters::Lower);
00322 
00323     /**
00324      * Construct a functor using the given parameters
00325      */
00326     backSubstitution(const parameters& par);
00327 
00328     /**
00329      * copy constructor
00330      * @param other the object to be copied
00331      */
00332     backSubstitution(const backSubstitution& other);
00333 
00334     /**
00335      * destructor
00336      */
00337     virtual ~backSubstitution();
00338 
00339     /**
00340      * returns the name of this type ("backSubstitution")
00341      */
00342     virtual const char* getTypeName() const;
00343 
00344     //TODO: comment your apply methods!
00345     
00346 
00347     /**
00348      * Performs backsubstitution with unknown \a x.  U*x=b if \a
00349      * theMatrix is upper triagonal and x*L=b if \a theMatrix is lower
00350      * triagonal. The result \a x is left in \a b. The matrix in the
00351      * parameters is used.
00352      *
00353      * @param b the right side of the backsubstitution. The result
00354      *          will be left here too.
00355      * @return true if apply successful or false otherwise.
00356      */
00357     bool apply(vector<T>& b) const;
00358 
00359     /**
00360      * Performs backsubstitution with unknown \a x.  U*x=b if \a
00361      * theMatrix is upper triagonal and x*L=b if \a theMatrix is lower
00362      * triagonal. The matrix in the parameters is used.
00363      *
00364      * @param b the right side of the backsubstitution. 
00365      * @param x the result.
00366      * @return true if apply successful or false otherwise.
00367      */
00368     bool apply(const vector<T>& b, vector<T>& x) const;
00369 
00370     /**
00371      * Performs backsubstitution with unknown \a x.  U*x=b if \a
00372      * theMatrix is upper triagonal and x*L=b if \a theMatrix is lower
00373      * triagonal. The result \a x is left in \a b. 
00374      *
00375      * @param theMatrix data matrix (L or U)
00376      * @param b the right side of the backsubstitution. The result
00377      *          will be left here too.
00378      * @param tType defines whether theMatrix is lower or upper triangular
00379      * @return true if apply successful or false otherwise.
00380      */
00381     bool apply(const matrix<T>& theMatrix, vector<T>& b,
00382                const typename parameters::eTriangularType& tType) const;
00383 
00384     /**
00385      * Performs backsubstitution with unknown \a x.  U*x=b if \a
00386      * theMatrix is upper triagonal and x*L=b if \a theMatrix is lower
00387      * triagonal. 
00388      *
00389      * @param theMatrix data matrix (L or U)
00390      * @param b the right side of the backsubstitution. The result
00391      *          will be left here too.
00392      * @param x the result.
00393      * @param tType defines whether theMatrix is lower or upper triangular
00394      * @return true if apply successful or false otherwise.
00395      */
00396     bool apply(const matrix<T>& theMatrix, const vector<T>& b,
00397                vector<T>& x, 
00398                const typename parameters::eTriangularType& tType) const;
00399 
00400 
00401     /**
00402      * Performs backsubstitution with unknowns \a X.  U*X=B if \a
00403      * theMatrix is upper triagonal and X*L=B if \a theMatrix is lower
00404      * triagonal. In the first case \a X and \a B contain the vectors
00405      * in colums, in the latter case in rows. The result \a x is left
00406      * in \a b. The matrix in the parameters is used.
00407      *
00408      * @param b the right side of the backsubstitution. The result
00409      *          will be left here too.
00410      * @return true if apply successful or false otherwise.
00411      */
00412     bool apply(matrix<T>& b) const;
00413 
00414     /**
00415      * Performs backsubstitution with unknowns \a X.  U*X=B if \a
00416      * theMatrix is upper triagonal and X*L=B if \a theMatrix is lower
00417      * triagonal. In the first case \a X and \a B contain the vectors
00418      * in colums, in the latter case in rows. The data matrix in the
00419      * parameters is used.
00420      *
00421      * @param b the right side of the backsubstitution. 
00422      * @param x the result
00423      * @return true if apply successful or false otherwise.
00424      */
00425     bool apply(const matrix<T>& b, matrix<T>& x) const;
00426 
00427     /**
00428      * Performs backsubstitution with unknowns \a X.  U*X=B if \a
00429      * theMatrix is upper triagonal and X*L=B if \a theMatrix is lower
00430      * triagonal. In the first case \a X and \a B contain the vectors
00431      * in colums, in the latter case in rows. The result \a x is left
00432      * in \a b.
00433      *
00434      * @param theMatrix data matrix (L or U)
00435      * @param b the right side of the backsubstitution. The result
00436      *          will be left here too.
00437      * @param tType defines whether theMatrix is lower or upper triangular
00438      * @return true if apply successful or false otherwise.
00439      */
00440     bool apply(const matrix<T>& theMatrix, matrix<T>& b, 
00441                const typename parameters::eTriangularType& tType) const;
00442 
00443     /**
00444      * Performs backsubstitution with unknowns \a X.  U*X=B if \a
00445      * theMatrix is upper triagonal and X*L=B if \a theMatrix is lower
00446      * triagonal. In the first case \a X and \a B contain the vectors
00447      * in colums, in the latter case in rows.
00448      *
00449      * @param theMatrix data matrix (L or U)
00450      * @param b the right side of the backsubstitution. The result
00451      *          will be left here too.
00452      * @param x the result
00453      * @param tType defines whether theMatrix is lower or upper triangular
00454      * @return true if apply successful or false otherwise.
00455      */
00456     bool apply(const matrix<T>& theMatrix, const matrix<T>& b, 
00457                matrix<T>& x, 
00458                const typename parameters::eTriangularType& tType) const;
00459 
00460     /**
00461      * copy data of "other" functor.
00462      * @param other the functor to be copied
00463      * @return a reference to this functor object
00464      */
00465     backSubstitution& copy(const backSubstitution& other);
00466 
00467     /**
00468      * alias for copy member
00469      * @param other the functor to be copied
00470      * @return a reference to this functor object
00471      */
00472     backSubstitution& operator=(const backSubstitution& other);
00473 
00474     /**
00475      * returns a pointer to a clone of this functor.
00476      */
00477     virtual functor* clone() const;
00478 
00479     /**
00480      * returns used parameters
00481      */
00482     const parameters& getParameters() const;
00483 
00484     //TODO: comment the attributes of your functor
00485     // If you add more attributes manually, do not forget to do following:
00486     // 1. indicate in the default constructor the default values
00487     // 2. make sure that the copy member also copy your new attributes, or
00488     //    to ensure there, that these attributes are properly initialized.
00489 
00490   };
00491 }
00492 
00493 #endif

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