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

ltiGeneralizedEigenSystem.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 .......: ltiGeneralizedEigenSystem.h
00027  * authors ....: Peter Doerfler
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 10.7.2003
00030  * revisions ..: $Id: ltiGeneralizedEigenSystem.h,v 1.10 2006/02/08 12:24:25 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_GENERALIZED_EIGEN_SYSTEM_H_
00034 #define _LTI_GENERALIZED_EIGEN_SYSTEM_H_
00035 
00036 #include "ltiLinearAlgebraFunctor.h"
00037 #include "ltiVector.h"
00038 #include "ltiMatrix.h"
00039 #include "ltiCholeskyDecomposition.h"
00040 #include "ltiForwardSubstitution.h"
00041 #include "ltiBackSubstitution.h"
00042 #include "ltiEigenSystem.h"
00043 
00044 namespace lti {
00045   /**
00046    *  Computes all the eigenvalues, and optionally, the eigenvectors
00047    *  of a real generalized symmetric-definite eigenproblem, of the
00048    *  form A*x=(lambda)*B*x.  Here A and B are assumed to be symmetric
00049    *  and B is also positive definite.
00050    *
00051    *  If parameters::sort is true the eigenvalues and corresponding
00052    *  eigenvectors are sorted in descending order. Default is true.
00053    */
00054   template<class T>
00055   class generalizedEigenSystem : public linearAlgebraFunctor {
00056   public:
00057     /**
00058      * the parameters for the class generalizedEigenSystem
00059      */
00060     class parameters : public eigenSystem<T>::parameters {
00061     public:
00062       /**
00063        * default constructor. Set sort to true.
00064        */
00065       parameters() : eigenSystem<T>::parameters(), dimensions(0) {
00066         
00067       };
00068 
00069       /**
00070        * copy constructor
00071        * @param other the parameters object to be copied
00072        */
00073       parameters(const parameters& other) : eigenSystem<T>::parameters() {
00074         copy(other);
00075       }
00076       
00077       /**
00078        * destructor
00079        */
00080       ~parameters() {
00081       };
00082 
00083       /**
00084        * returns name of this type
00085        */
00086       const char* getTypeName() const {
00087         return "generalizedEigenSystem::parameters";
00088       };
00089 
00090       /**
00091        * copy the contents of a parameters object
00092        * @param other the parameters object to be copied
00093        * @return a reference to this parameters object
00094        */
00095       parameters& copy(const parameters& other) {
00096 #     ifndef _LTI_MSC_6
00097         // MS Visual C++ 6 is not able to compile this...
00098         eigenSystem<T>::parameters::copy(other);
00099 #     else
00100         // ...so we have to use this workaround.
00101         // Conditional on that, copy may not be virtual.
00102         functor::parameters& (functor::parameters::* p_copy)
00103                             (const functor::parameters&) =
00104                             functor::parameters::copy;
00105         (this->*p_copy)(other);
00106 #     endif
00107 
00108         
00109         dimensions = other.dimensions;
00110 
00111         return *this;
00112       };
00113 
00114       /**
00115        * copy the contents of a parameters object
00116        * @param other the parameters object to be copied
00117        * @return a reference to this parameters object
00118        */
00119       parameters& operator=(const parameters& other) {
00120         return copy(other);
00121       };
00122 
00123       /**
00124        * returns a pointer to a clone of the parameters
00125        */
00126       virtual functor::parameters* clone() const {
00127         return new parameters(*this);
00128       };
00129 
00130 #     ifndef _LTI_MSC_6
00131       /**
00132        * write the parameters in the given ioHandler
00133        * @param handler the ioHandler to be used
00134        * @param complete if true (the default) the enclosing begin/end will
00135        *        be also written, otherwise only the data block will be written.
00136        * @return true if write was successful
00137        */
00138       virtual bool write(ioHandler& handler,const bool complete=true) const
00139 #     else
00140       /**
00141        * this function is required by MSVC only, as a workaround for a
00142        * very awful bug, which exists since MSVC V.4.0, and still by
00143        * V.6.0 with all bugfixes (so called "service packs") remains
00144        * there...  This method is also public due to another bug, so please
00145        * NEVER EVER call this method directly: use write() instead
00146        */
00147       bool writeMS(ioHandler& handler,const bool complete=true) const
00148 #     endif
00149       {
00150         bool b = true;
00151         if (complete) {
00152           b = handler.writeBegin();
00153         }
00154         
00155         if (b) {
00156           
00157           lti::write(handler,"dimensions",dimensions);
00158         }
00159 
00160 #     ifndef _LTI_MSC_6
00161         // This is the standard C++ code, which MS Visual C++ 6 is not able to
00162         // compile...
00163         b = b && eigenSystem<T>::parameters::write(handler,false);
00164 #     else
00165         bool (eigenSystem<T>::parameters::* p_writeMS)(ioHandler&,
00166                                                          const bool) const =
00167           eigenSystem<T>::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       /**
00180        * write the parameters in the given ioHandler
00181        * @param handler the ioHandler to be used
00182        * @param complete if true (the default) the enclosing begin/end will
00183        *        be also written, otherwise only the data block will be written.
00184        * @return true if write was successful
00185        */
00186       bool write(ioHandler& handler,
00187                  const bool complete=true) const {
00188         // ...we need this workaround to cope with another really
00189         // awful MSVC bug.
00190         return writeMS(handler,complete);
00191       }
00192 #     endif
00193 
00194 
00195 #     ifndef _LTI_MSC_6
00196       /**
00197        * read the parameters from the given ioHandler
00198        * @param handler the ioHandler to be used
00199        * @param complete if true (the default) the enclosing begin/end will
00200        *        be also written, otherwise only the data block will be written.
00201        * @return true if write was successful
00202        */
00203       virtual bool read(ioHandler& handler,const bool complete=true)
00204 #     else
00205       /**
00206        * this function is required by MSVC only, as a workaround for a
00207        * very awful bug, which exists since MSVC V.4.0, and still by
00208        * V.6.0 with all bugfixes (so called "service packs") remains
00209        * there...  This method is also public due to another bug, so please
00210        * NEVER EVER call this method directly: use read() instead
00211        */
00212       bool readMS(ioHandler& handler,const bool complete=true)
00213 #     endif
00214       {
00215         bool b = true;
00216         if (complete) {
00217           b = handler.readBegin();
00218         }
00219         
00220         if (b) {
00221           
00222           lti::read(handler,"dimensions",dimensions);
00223         }
00224 
00225 #       ifndef _LTI_MSC_6
00226         // This is the standard C++ code, which MS Visual C++ 6 is not
00227         // able to compile...
00228         b = b && eigenSystem<T>::parameters::read(handler,false);
00229 #       else
00230         bool (eigenSystem<T>::parameters::* p_readMS)(ioHandler&,
00231                                                         const bool) =
00232           eigenSystem<T>::parameters::readMS;
00233         b = b && (this->*p_readMS)(handler,false);
00234 #       endif
00235 
00236         if (complete) {
00237           b = b && handler.readEnd();
00238         }
00239         
00240         return b;
00241       }
00242 
00243 #     ifdef _LTI_MSC_6
00244       /**
00245        * read the parameters from the given ioHandler
00246        * @param handler the ioHandler to be used
00247        * @param complete if true (the default) the enclosing begin/end will
00248        *        be also written, otherwise only the data block will be written.
00249        * @return true if write was successful
00250        */
00251       bool read(ioHandler& handler,const bool complete=true) {
00252         // ...we need this workaround to cope with another really awful MSVC
00253         // bug.
00254         return readMS(handler,complete);
00255       }
00256 #     endif
00257 
00258       // ------------------------------------------------
00259       // the parameters
00260       // ------------------------------------------------
00261 
00262       //TODO: comment the parameters of your functor
00263       // If you add more parameters manually, do not forget to do following:
00264       // 1. indicate in the default constructor the default values
00265       // 2. make sure that the copy member also copy your new parameters
00266       // 3. make sure that the read and write members also read and
00267       //    write your parameters
00268       
00269 
00270       /**
00271        * number of dimensions calculated. The default is zero. In this
00272        * case, all eigenvectors and eigenvalues are calculated.
00273        *
00274        * This option is only provided for compatibility with the
00275        * fastGeneralizedEigenSystem functor based on LAPACK, but it
00276        * does not make (yet) the computation of the eigensolution any
00277        * faster.  It just will cut the already computed complete
00278        * solution to the desired size!
00279        *
00280        * Default value: 0 (implying all eigenvalues will be computed)
00281        */
00282       int dimensions;
00283 
00284     };
00285 
00286     /**
00287      * default constructor
00288      */
00289     generalizedEigenSystem();
00290 
00291     /**
00292      * Construct a functor using the given parameters
00293      */
00294     generalizedEigenSystem(const parameters& par);
00295 
00296     /**
00297      * copy constructor
00298      * @param other the object to be copied
00299      */
00300     generalizedEigenSystem(const generalizedEigenSystem& other);
00301 
00302     /**
00303      * destructor
00304      */
00305     virtual ~generalizedEigenSystem();
00306 
00307     /**
00308      * returns the name of this type ("generalizedEigenSystem")
00309      */
00310     virtual const char* getTypeName() const;
00311 
00312     /**
00313      * Computes eigenvalues and eigenvectors of the given matrix. The
00314      * functor can efficiently calculate only a few dimensions of the
00315      * eigenspace, taking those with the largest eigenvalues. The
00316      * number of dimensions is set with parameters::dimensions.
00317      *
00318      * @param a the symmetric matrix A
00319      * @param b the symmetric, positive definite matrix B
00320      * @param eigenvalues  elements will contain the eigenvalues
00321      * @param eigenvectors columns will contain the  eigenvectors
00322      *                     corresponding to the eigenvalues
00323      */
00324     virtual bool apply(const matrix<T>& a,
00325                        const matrix<T>& b,
00326                        vector<T>& eigenvalues,
00327                        matrix<T>& eigenvectors) const;
00328 
00329     /**
00330      * Computes eigenvalues and eigenvectors of the given matrix. The
00331      * functor can efficiently calculate only a few dimensions of the
00332      * eigenspace, taking those with the largest eigenvalues. The
00333      * number of dimensions is set with parameters::dimensions.
00334      *
00335      * @param a the symmetric matrix A
00336      * @param b the symmetric, positive definite matrix B
00337      * @param eigenvalues  elements will contain the eigenvalues
00338      */
00339     virtual bool apply(const matrix<T>& a,
00340                        const matrix<T>& b,
00341                        vector<T>& eigenvalues) const;
00342 
00343     /**
00344      * copy data of "other" functor.
00345      * @param other the functor to be copied
00346      * @return a reference to this functor object
00347      */
00348     generalizedEigenSystem& copy(const generalizedEigenSystem& other);
00349 
00350     /**
00351      * alias for copy member
00352      * @param other the functor to be copied
00353      * @return a reference to this functor object
00354      */
00355     generalizedEigenSystem& operator=(const generalizedEigenSystem& other);
00356 
00357     /**
00358      * returns a pointer to a clone of this functor.
00359      */
00360     virtual functor* clone() const;
00361 
00362     /**
00363      * returns used parameters
00364      */
00365     const parameters& getParameters() const;
00366 
00367     /**
00368      * set functor's parameters.
00369      * This member makes a copy of <em>theParam</em>: the functor
00370      * will keep its own copy of the parameters!
00371      * @return true if successful, false otherwise
00372      */
00373     virtual bool updateParameters();
00374 
00375   private:
00376 
00377     choleskyDecomposition<T> cholesky;
00378     
00379     forwardSubstitution<T> fSubst;
00380     backSubstitution<T> bSubst;
00381 
00382     jacobi<T> simpleEigen;
00383   };
00384 }
00385 
00386 #endif

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