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

ltiEigenSystem.h

00001 /*
00002  * Copyright (C) 1999, 2000, 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 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiEigenSystem.h
00027  * authors ....: Thomas Rusert
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 16.06.99
00030  * revisions ..: $Id: ltiEigenSystem.h,v 1.8 2006/02/08 12:18:44 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_EIGEN_SYSTEM_H_
00034 #define _LTI_EIGEN_SYSTEM_H_
00035 
00036 #include "ltiMatrix.h"
00037 #include "ltiVector.h"
00038 #include "ltiLinearAlgebraFunctor.h"
00039 
00040 namespace lti {
00041   /**
00042    * eigenSystem functor.
00043    *
00044    * Base class for Eigenvalue and Eigenvector computation functors.
00045    *
00046    * Please note that the eigenvector matrices will contain the
00047    * eigenvector in the COLUMNS and not in the rows, as could be
00048    * expected.  This avoids the requirement of transposing matrices in
00049    * eigenvector-based transformations like PCA!
00050    */
00051   template<class T>
00052   class eigenSystem : public linearAlgebraFunctor {
00053   public:
00054     /**
00055      * eigenSystem parameter class
00056      */
00057     class parameters : public linearAlgebraFunctor::parameters {
00058     public:
00059       /**
00060        * default constructor
00061        */
00062       parameters() : linearAlgebraFunctor::parameters(),sort(false) {
00063       };
00064 
00065       /**
00066        * copy constructor
00067        */
00068       parameters(const parameters& other)
00069         : linearAlgebraFunctor::parameters() {copy(other);};
00070 
00071       /**
00072        * returns the name of this type
00073        */
00074       virtual const char* getTypeName() const {
00075         return "eigenSystem::parameters";
00076       };
00077 
00078       /**
00079        * copy member.
00080        */
00081       parameters& copy(const parameters& other) {
00082 #ifndef _LTI_MSC_6
00083         // MS Visual C++ 6 is not able to compile this...
00084         linearAlgebraFunctor::parameters::copy(other);
00085 #else
00086         // ...so we have to use this workaround.
00087         // Conditional on that, copy may not be virtual.
00088         functor::parameters&
00089           (functor::parameters::* p_copy)(const functor::parameters&) =
00090           functor::parameters::copy;
00091         (this->*p_copy)(other);
00092 #endif
00093         sort = other.sort;
00094 
00095         return (*this);
00096       };
00097 
00098       /**
00099        * returns a pointer to a clone of the parameters.
00100        */
00101       virtual functor::parameters* clone() const {
00102         return (new parameters(*this));
00103       };
00104 
00105       // ---------------------------------------------------
00106       // the parameters
00107       // ---------------------------------------------------
00108 
00109       /**
00110        * If true, the eigenvalues and corresponding eigenvectors will be
00111        * sorted in decreasing order of the eigenvalues.
00112        *
00113        * Default value: false
00114        */
00115       bool sort;
00116 
00117     };
00118 
00119     /**
00120      * default constructor
00121      */
00122     eigenSystem()
00123       : linearAlgebraFunctor() {};
00124 
00125     /**
00126      * constructor, sets the parameters
00127      */
00128     eigenSystem(const parameters& theParams);
00129 
00130     /**
00131      * constructor, sets the parameters
00132      */
00133     eigenSystem(const bool theSort);
00134 
00135     /**
00136      * destructor
00137      */
00138     virtual ~eigenSystem() {};
00139 
00140     /**
00141      * returns the current parameters.
00142      */
00143     const parameters& getParameters() const;
00144 
00145     /**
00146      * onCopy version of apply.
00147      * @param theMatrix matrix to be transformed
00148      * @param eigenvalues elements will contain the eigenvalues
00149      * @param eigenvectors columns will contain the eigenvectors
00150      *        corresponding to the eigenvalues
00151      * @return bool true if successful, false otherwise.
00152      */
00153     virtual bool apply(const matrix<T>& theMatrix,
00154                        vector<T>& eigenvalues,
00155                        matrix<T>& eigenvectors) const=0;
00156 
00157     /**
00158      * returns the name of this type
00159      */
00160     virtual const char* getTypeName() const {
00161       return "eigenSystem";
00162     };
00163   };
00164 
00165   /**
00166    * jacobi functor.
00167    * This functor computes all eigenvalues and eigenvectors of a
00168    * real _symmetric and square_ matrix using the Jacobi method.
00169    *
00170    * Please note that the eigenvector matrices will contain the
00171    * eigenvector in the COLUMNS and not in the rows, as could be
00172    * expected.  This avoids the requirement of transposing matrices in
00173    * eigenvector-based transformations like PCA!  All eigenvector functors
00174    * follows this interface.
00175    */
00176   template<class T>
00177   class jacobi : public eigenSystem<T> {
00178   public:
00179 
00180     /**
00181      * eigenSystem parameter class
00182      */
00183     class parameters : public eigenSystem<T>::parameters {
00184     public:
00185       /**
00186        * default constructor
00187        */
00188       parameters()
00189         : eigenSystem<T>::parameters(),dimensions(0) {
00190       };
00191 
00192       /**
00193        * copy constructor
00194        */
00195       parameters(const parameters& other) {
00196         copy(other);
00197       };
00198 
00199       /**
00200        * number of dimensions calculated. The default is zero. In this
00201        * case, all eigenvectors and eigenvalues are calculated.
00202        *
00203        * This option is only provided for compatibility with the
00204        * fastEigenSystem functor based on LAPACK, but it does not make (yet)
00205        * the computation of the eigensolution any faster.  It just will cut
00206        * the already computed complete solution to the desired size!
00207        *
00208        * Default value: 0 (implying all eigenvalues will be computed)
00209        */
00210       int dimensions;
00211 
00212       /**
00213        * returns the name of this type
00214        */
00215       virtual const char* getTypeName() const {
00216         return "fastEigenSystem::parameters";
00217       };
00218 
00219       /**
00220        * copy member.
00221        */
00222       parameters& copy(const parameters& other) {
00223 #ifndef _LTI_MSC_6
00224         // MS Visual C++ 6 is not able to compile this...
00225         eigenSystem<T>::parameters::copy(other);
00226 #else
00227         // ...so we have to use this workaround.
00228         // Conditional on that, copy may not be virtual.
00229         eigenSystem<T>::parameters&
00230           (eigenSystem<T>::parameters::* p_copy)(const eigenSystem<T>::parameters&) =
00231           eigenSystem<T>::parameters::copy;
00232         (this->*p_copy)(other);
00233 #endif
00234         dimensions=other.dimensions;
00235 
00236         return (*this);
00237       };
00238 
00239       /**
00240        * returns a pointer to a clone of the parameters.
00241        */
00242       virtual functor::parameters* clone() const {
00243         return (new parameters(*this));
00244       };
00245     };
00246 
00247 
00248     /**
00249      * default constructor
00250      */
00251     jacobi();
00252 
00253     /**
00254      * default constructor with parameters
00255      */
00256     jacobi(const parameters& params);
00257 
00258 
00259     /**
00260      * onCopy version of apply.
00261      * @param theMatrix  Real symmetric matrix to be transformed.
00262      * Only the diagonal and above diagonal elements have
00263      * to be set.
00264      * @param eigenvalues  Elements will contain the eigenvalues.
00265      * @param eigenvectors Columns will contain the eigenvectors corresponding
00266      * to the eigenvalues.
00267      * returns true if successful, false otherwise.
00268      */
00269     virtual bool apply(const matrix<T>& theMatrix,
00270                        vector<T>& eigenvalues,
00271                        matrix<T>& eigenvectors) const;
00272 
00273     /**
00274      * returns a pointer to a clone of the functor.
00275      */
00276     virtual functor* clone() const { return (new jacobi<T>(*this));};
00277 
00278     /**
00279      * returns the name of this type
00280      */
00281     virtual const char* getTypeName() const {return "jacobi";};
00282 
00283     /**
00284      * returns the current parameters.
00285      */
00286     const parameters& getParameters() const;
00287 
00288   protected:
00289     inline void rotateT(double& g,double& h,matrix<T>& a,
00290                         const int i,const int j,const int k,const int l,
00291                         const double s,const double tau) const;
00292 
00293     inline void rotate(double& g,double& h,matrix<double>& a,
00294                        const int i,const int j,const int k,const int l,
00295                        const double s,const double tau) const;
00296 
00297 
00298   };
00299 }
00300 
00301 
00302 #endif

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