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

ltiUnifiedGeneralizedEigenSystem.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 .......: ltiUnifiedGeneralizedEigenSystem.h
00027  * authors ....: Peter Doerfler
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 21.11.2003
00030  * revisions ..: $Id: ltiUnifiedGeneralizedEigenSystem.h,v 1.8 2006/02/08 12:50:16 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_UNIFIED_GENERALIZED_EIGEN_SYSTEM_H_
00034 #define _LTI_UNIFIED_GENERALIZED_EIGEN_SYSTEM_H_
00035 
00036 #include "ltiGeneralizedEigenSystem.h"
00037 #include "ltiLinearAlgebraFunctor.h"
00038 
00039 
00040 namespace lti {
00041   /**
00042    * This functor is meant to be used for solving any generalized
00043    * Eigenvalue problem without need to think about the most efficient
00044    * usage of the available methods. If the LAPACK is available it
00045    * will automatically be used since it is much faster. 
00046    *
00047    * This functor only handles generalized Eigenvalue problems. For
00048    * non-generalized EV problems use there is only a LAPACK functor:
00049    * genEigenSystem. For the generalized eigenvalue problem either
00050    * generalizedEigenSystem or fastGeneralizedEigenSystem can be used.
00051    *
00052    * It is preferred to use this class instead of the generalized
00053    * eigenSystem functors available.
00054    */
00055   template<class T>
00056   class unifiedGeneralizedEigenSystem : public linearAlgebraFunctor {
00057   public:
00058     /**
00059      * the parameters for the class unifiedGeneralizedEigenSystem.
00060      *
00061      * Note that the parameter problemType of
00062      * fastGeneralizedEigenSystem is statically set to Type1 in this
00063      * functor, which results in the same functionality as that of
00064      * generalizedEigenSystem. If you need other types use the LAPACK
00065      * method directly.
00066      */
00067     class parameters : public linearAlgebraFunctor::parameters {
00068     public:
00069 
00070       /**
00071        * The Eigensystem solution method to use. Note that functors
00072        * starting with Fast___ are only available if LAPACK is
00073        * used. The default is set according to your installation.
00074        */
00075       enum eEigenSystemType {
00076         GeneralizedEigenSystem,         /*!< use generalizedEigenSystem */
00077         FastGeneralizedEigenSystem = 10 /*!< use fastGeneralizedEigenSystem */
00078       };
00079 
00080       /**
00081        * default constructor
00082        */
00083       parameters() : linearAlgebraFunctor::parameters() {
00084         
00085         sort = true;
00086         dimensions = 0;
00087         useDC = true;
00088 #ifdef HAVE_LAPACK
00089         esType = FastGeneralizedEigenSystem;
00090 #else
00091         esType = GeneralizedEigenSystem;
00092 #endif
00093       };
00094 
00095       /**
00096        * copy constructor
00097        * @param other the parameters object to be copied
00098        */
00099       parameters(const parameters& other) : linearAlgebraFunctor::parameters() {
00100         copy(other);
00101       }
00102       
00103       /**
00104        * destructor
00105        */
00106       ~parameters() {
00107       };
00108 
00109       /**
00110        * returns name of this type
00111        */
00112       const char* getTypeName() const {
00113         return "unifiedGeneralizedEigenSystem::parameters";
00114       };
00115 
00116       /**
00117        * copy the contents of a parameters object
00118        * @param other the parameters object to be copied
00119        * @return a reference to this parameters object
00120        */
00121       parameters& copy(const parameters& other) {
00122 #     ifndef _LTI_MSC_6
00123         // MS Visual C++ 6 is not able to compile this...
00124         linearAlgebraFunctor::parameters::copy(other);
00125 #     else
00126         // ...so we have to use this workaround.
00127         // Conditional on that, copy may not be virtual.
00128         linearAlgebraFunctor::parameters& (linearAlgebraFunctor::parameters::* p_copy)
00129                             (const linearAlgebraFunctor::parameters&) =
00130                             linearAlgebraFunctor::parameters::copy;
00131         (this->*p_copy)(other);
00132 #     endif
00133 
00134         
00135         sort = other.sort;
00136         dimensions = other.dimensions;
00137         esType = other.esType;
00138         
00139         return *this;
00140       };
00141 
00142       /**
00143        * copy the contents of a parameters object
00144        * @param other the parameters object to be copied
00145        * @return a reference to this parameters object
00146        */
00147       parameters& operator=(const parameters& other) {
00148         return copy(other);
00149       };
00150 
00151       /**
00152        * returns a pointer to a clone of the parameters
00153        */
00154       virtual functor::parameters* clone() const {
00155         return new parameters(*this);
00156       };
00157 
00158 #     ifndef _LTI_MSC_6
00159       /**
00160        * write the parameters in the given ioHandler
00161        * @param handler the ioHandler to be used
00162        * @param complete if true (the default) the enclosing begin/end will
00163        *        be also written, otherwise only the data block will be written.
00164        * @return true if write was successful
00165        */
00166       virtual bool write(ioHandler& handler,const bool complete=true) const
00167 #     else
00168       /**
00169        * this function is required by MSVC only, as a workaround for a
00170        * very awful bug, which exists since MSVC V.4.0, and still by
00171        * V.6.0 with all bugfixes (so called "service packs") remains
00172        * there...  This method is also public due to another bug, so please
00173        * NEVER EVER call this method directly: use write() instead
00174        */
00175       bool writeMS(ioHandler& handler,const bool complete=true) const
00176 #     endif
00177       {
00178         bool b = true;
00179         if (complete) {
00180           b = handler.writeBegin();
00181         }
00182         
00183         if (b) {
00184           
00185           lti::write(handler,"sort",sort);
00186           lti::write(handler,"dimensions",dimensions);
00187           
00188           switch (esType) {
00189             case GeneralizedEigenSystem:
00190               lti::write(handler,"esType","GeneralizedEigenSystem");
00191               break;
00192             case FastGeneralizedEigenSystem:
00193               lti::write(handler,"esType","FastGeneralizedEigenSystem");
00194               break;
00195             default:
00196 #ifdef HAVE_LAPACK
00197               lti::write(handler,"esType","FastGeneralizedEigenSystem");
00198 #else              
00199               lti::write(handler,"esType","GeneralizedEigenSystem");
00200 #endif
00201               break;
00202           }
00203 
00204         }
00205 
00206 #     ifndef _LTI_MSC_6
00207         // This is the standard C++ code, which MS Visual C++ 6 is not able to
00208         // compile...
00209         b = b && linearAlgebraFunctor::parameters::write(handler,false);
00210 #     else
00211         bool (linearAlgebraFunctor::parameters::* p_writeMS)(ioHandler&,
00212                                                          const bool) const =
00213           linearAlgebraFunctor::parameters::writeMS;
00214         b = b && (this->*p_writeMS)(handler,false);
00215 #     endif
00216 
00217         if (complete) {
00218           b = b && handler.writeEnd();
00219         }
00220 
00221         return b;
00222       }
00223 
00224 #     ifdef _LTI_MSC_6
00225       /**
00226        * write the parameters in the given ioHandler
00227        * @param handler the ioHandler to be used
00228        * @param complete if true (the default) the enclosing begin/end will
00229        *        be also written, otherwise only the data block will be written.
00230        * @return true if write was successful
00231        */
00232       bool write(ioHandler& handler,
00233                  const bool complete=true) const {
00234         // ...we need this workaround to cope with another really
00235         // awful MSVC bug.
00236         return writeMS(handler,complete);
00237       }
00238 #     endif
00239 
00240 
00241 #     ifndef _LTI_MSC_6
00242       /**
00243        * read the parameters from the given ioHandler
00244        * @param handler the ioHandler to be used
00245        * @param complete if true (the default) the enclosing begin/end will
00246        *        be also written, otherwise only the data block will be written.
00247        * @return true if write was successful
00248        */
00249       virtual bool read(ioHandler& handler,const bool complete=true)
00250 #     else
00251       /**
00252        * this function is required by MSVC only, as a workaround for a
00253        * very awful bug, which exists since MSVC V.4.0, and still by
00254        * V.6.0 with all bugfixes (so called "service packs") remains
00255        * there...  This method is also public due to another bug, so please
00256        * NEVER EVER call this method directly: use read() instead
00257        */
00258       bool readMS(ioHandler& handler,const bool complete=true)
00259 #     endif
00260       {
00261         bool b = true;
00262         if (complete) {
00263           b = handler.readBegin();
00264         }
00265         
00266         if (b) {
00267           
00268           lti::read(handler,"sort",sort);
00269           lti::read(handler,"dimensions",dimensions);
00270 
00271           std::string tmp;
00272           lti::read(handler,"esType",tmp);
00273           if (tmp=="GeneralizedEigenSystem") {
00274             esType = GeneralizedEigenSystem;
00275           } else if (tmp=="FastGeneralizedEigenSystem") {
00276             esType = FastGeneralizedEigenSystem;
00277           } else {
00278 #ifdef HAVE_LAPACK
00279             esType = FastGeneralizedEigenSystem;
00280 #else
00281             esType = GeneralizedEigenSystem;
00282 #endif
00283           }
00284 
00285         }
00286 
00287 #       ifndef _LTI_MSC_6
00288         // This is the standard C++ code, which MS Visual C++ 6 is not
00289         // able to compile...
00290         b = b && linearAlgebraFunctor::parameters::read(handler,false);
00291 #       else
00292         bool (linearAlgebraFunctor::parameters::* p_readMS)(ioHandler&,
00293                                                         const bool) =
00294           linearAlgebraFunctor::parameters::readMS;
00295         b = b && (this->*p_readMS)(handler,false);
00296 #       endif
00297 
00298         if (complete) {
00299           b = b && handler.readEnd();
00300         }
00301         
00302         return b;
00303       }
00304 
00305 #     ifdef _LTI_MSC_6
00306       /**
00307        * read the parameters from the given ioHandler
00308        * @param handler the ioHandler to be used
00309        * @param complete if true (the default) the enclosing begin/end will
00310        *        be also written, otherwise only the data block will be written.
00311        * @return true if write was successful
00312        */
00313       bool read(ioHandler& handler,const bool complete=true) {
00314         // ...we need this workaround to cope with another really awful MSVC
00315         // bug.
00316         return readMS(handler,complete);
00317       }
00318 #     endif
00319 
00320       // ------------------------------------------------
00321       // the parameters
00322       // ------------------------------------------------
00323 
00324 
00325       /**
00326        * If true the eigenvalues and eigenvectors are sorted in
00327        * descending order. Default true.
00328        *
00329        * See eigenSystem<T>::parameters::sort.
00330        */
00331       bool sort;
00332 
00333       /**
00334        * The number of eigenvalues/-vectors to be calculated. If zero
00335        * all EV are calculated. Default 0.
00336        *
00337        * See also:
00338        * - generalizedEigenSystem<T>::parameters::dimensions
00339        * - fastGeneralizedEigenSystem<T>::parameters::dimensions
00340        */
00341       int dimensions;
00342 
00343       /**
00344        * The eigenSystem given is used. Note that you cannot use
00345        * fastGeneralizedEigenSystem if LAPACK is not installed. The
00346        * default is dependent on the the system configuration: If
00347        * LAPACK is available, fastGeneralizedEigenSystem is used,
00348        * otherwise generalizedEigenSystem.
00349        */
00350       eEigenSystemType esType;
00351 
00352       /**
00353        * This parameters is used only if
00354        * esType==FastGeneralizedEigenSystem. It determines whether the
00355        * divide and conquer strategy is used or not. Default true.
00356        *
00357        * See fastGeneralizedEigenSystem<T>::parameters::useDC
00358        */
00359       bool useDC;
00360 
00361     };
00362 
00363     /**
00364      * default constructor
00365      */
00366     unifiedGeneralizedEigenSystem();
00367 
00368     /**
00369      * Construct a functor using the given parameters
00370      */
00371     unifiedGeneralizedEigenSystem(const parameters& par);
00372 
00373     /**
00374      * copy constructor
00375      * @param other the object to be copied
00376      */
00377     unifiedGeneralizedEigenSystem(const unifiedGeneralizedEigenSystem& other);
00378 
00379     /**
00380      * destructor
00381      */
00382     virtual ~unifiedGeneralizedEigenSystem();
00383 
00384     /**
00385      * returns the name of this type ("unifiedGeneralizedEigenSystem")
00386      */
00387     virtual const char* getTypeName() const;
00388 
00389     /**
00390      * copy data of "other" functor.
00391      * @param other the functor to be copied
00392      * @return a reference to this functor object
00393      */
00394     unifiedGeneralizedEigenSystem& 
00395     copy(const unifiedGeneralizedEigenSystem& other);
00396 
00397     /**
00398      * alias for copy member
00399      * @param other the functor to be copied
00400      * @return a reference to this functor object
00401      */
00402     unifiedGeneralizedEigenSystem& 
00403     operator=(const unifiedGeneralizedEigenSystem& other);
00404 
00405     /**
00406      * returns a pointer to a clone of this functor.
00407      */
00408     virtual functor* clone() const;
00409 
00410     /**
00411      * Update functor's parameters.
00412      *
00413      * Update some internal data according to the parameters.
00414      *
00415      * @return true if successful, false otherwise
00416      */
00417     virtual bool updateParameters();
00418 
00419     /**
00420      * returns used parameters
00421      */
00422     const parameters& getParameters() const;
00423 
00424     /**
00425      * Read the functor from the given ioHandler. 
00426      *
00427      * This method automatically sets the correct eigensystem solver
00428      * that is given in the parameters and transfers the relevant
00429      * parameters to that functor.
00430      *
00431      * @param handler the ioHandler to be used
00432      * @param complete if true (the default) the enclosing begin/end will
00433      *        be also written, otherwise only the data block will be written.
00434      * @return true if write was successful
00435      */
00436     virtual bool read(ioHandler& handler,const bool complete=true);
00437 
00438     /**
00439      * Computes eigenvalues and eigenvectors of the given matrix. The
00440      * functor can efficiently calculate only a few dimensions of the
00441      * eigenspace, taking those with the largest eigenvalues. The
00442      * number of dimensions is set with parameters::dimensions.
00443      *
00444      * @param a the symmetric matrix A
00445      * @param b the symmetric, positive definite matrix B
00446      * @param eigenvalues  elements will contain the eigenvalues
00447      * @param eigenvectors columns will contain the  eigenvectors
00448      *                     corresponding to the eigenvalues
00449      */
00450     inline bool apply(const matrix<T>& a,
00451                       const matrix<T>& b,
00452                       vector<T>& eigenvalues,
00453                       matrix<T>& eigenvectors) const {
00454       return eigen->apply(a,b,eigenvalues,eigenvectors);
00455     }
00456 
00457     /**
00458      * Computes eigenvalues and eigenvectors of the given matrix. The
00459      * functor can efficiently calculate only a few dimensions of the
00460      * eigenspace, taking those with the largest eigenvalues. The
00461      * number of dimensions is set with parameters::dimensions.
00462      *
00463      * @param a the symmetric matrix A
00464      * @param b the symmetric, positive definite matrix B
00465      * @param eigenvalues  elements will contain the eigenvalues
00466      */
00467     inline bool apply(const matrix<T>& a,
00468                       const matrix<T>& b,
00469                       vector<T>& eigenvalues) const {
00470       return eigen->apply(a,b,eigenvalues);
00471     }
00472     
00473   protected:
00474     
00475     /**
00476      * The actual eigenSystem.
00477      */
00478     generalizedEigenSystem<T>* eigen;
00479     
00480   };
00481 }
00482 
00483 #endif

Generated on Sat Apr 10 15:26:20 2010 for LTI-Lib by Doxygen 1.6.1