CVR-Lib last update 20 Sep 2009

cvrSymmetricEigenSystem.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2005
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 /**
00042  * \file   cvrSymmetricEigenSystem.h
00043  *         Contains the template class symmetricEigenSystem<T> that
00044  *         uses LAPACK if available.
00045  * \author Thomas Rusert
00046  * \author Peter Doerfler
00047  * \date   16.06.99
00048  *
00049  * $Id: cvrSymmetricEigenSystem.h,v 1.4 2006/09/07 13:38:37 doerfler Exp $
00050  */
00051 
00052 #ifndef _CVR_SYMMETRIC_EIGEN_SYSTEM_H_
00053 #define _CVR_SYMMETRIC_EIGEN_SYSTEM_H_
00054 
00055 #include "cvrMatrix.h"
00056 #include "cvrVector.h"
00057 #include "cvrLinearAlgebraFunctor.h"
00058 
00059 #include "cvrTypeInfo.h"
00060 
00061 #ifdef HAVE_LAPACK
00062 #  include "cvrLapackInterface.h"
00063 #endif
00064 
00065 namespace cvr {
00066   /**
00067    * Computes the Eigenvectors and Eigenvalues of a symmetric,
00068    * positive definite, real matrix.
00069    *
00070    * The most common source of such matrices is a covariance matrix
00071    * (see cvr::secondOrderStatistics).
00072    *
00073    * This class uses the LAPACK functions by default if they are
00074    * installed on your system. Otherwise a simple Jacobi algorithm is
00075    * used. This can also be chosen deliberately by setting
00076    * parameters::useLapack to false.
00077    *
00078    * The eigenvectors can be sorted according to their eigenvalues by
00079    * setting parameters::sort. A fixed number of eigenvectors can be
00080    * set via parameters::dimension. For LAPACK this also reduces
00081    * computation time.
00082    *
00083    * Please note that the eigenvector matrices will contain the
00084    * eigenvectors in the COLUMNS and not in the rows, as could be
00085    * expected. This avoids the requirement of transposing matrices in
00086    * eigenvector-based transformations like PCA!
00087    *
00088    * @ingroup gLinearAlgebra, gStatistics
00089    */
00090   template <typename T>
00091   class symmetricEigenSystem : public linearAlgebraFunctor
00092 #ifdef HAVE_LAPACK
00093     , public lapackInterface
00094 #endif
00095   {
00096   public:
00097 
00098     /**
00099      * eigenSystem parameter class
00100      */
00101     class parameters : public linearAlgebraFunctor::parameters {
00102     public:
00103       /**
00104        * default constructor
00105        */
00106       parameters();
00107 
00108       /**
00109        * copy constructor
00110        */
00111       parameters(const parameters& other);
00112 
00113       /**
00114        * copy member.
00115        */
00116       parameters& copy(const parameters& other);
00117 
00118       /**
00119        * Returns the name of this class.
00120        */
00121       const std::string& name() const;
00122 
00123       /**
00124        * returns a pointer to a clone of the parameters.
00125        */
00126       virtual parameters* clone() const;
00127 
00128       /**
00129        * returns a pointer to a clone of the parameters.
00130        */
00131       virtual parameters* newInstance() const;
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 written.
00138        * \return true if write was successful
00139        */
00140       virtual bool write(ioHandler& handler, const bool complete=true) const;
00141 
00142       /**
00143        * read the parameters from the given ioHandler
00144        * \param handler the ioHandler to be used
00145        * \param complete if true (the default) the enclosing begin/end will
00146        *        be also written, otherwise only the data block will be written.
00147        * \return true if write was successful
00148        */
00149       virtual bool read(ioHandler& handler, const bool complete=true);
00150 
00151 
00152       //****************************
00153       // the parameters
00154       //****************************
00155 
00156       /**
00157        * If true, the eigenvalues and corresponding eigenvectors will be
00158        * sorted in decreasing order of the eigenvalues.
00159        *
00160        * For complex-valued matrices a complex number will be considered
00161        * "greater than" another one if its real part is greater, or, if both
00162        * real components are identical, if its imaginary part is greater.
00163        * 
00164        * Default value: false
00165        */
00166       bool sort;
00167 
00168       /**
00169        * Mumber of dimensions calculated.
00170        *
00171        * If set to zero, then all eigenvectors and eigenvalues are calculated.
00172        *
00173        * This option is only provided for compatibility with the
00174        * fastEigenSystem functor based on LAPACK, but it does not make (yet)
00175        * the computation of the eigensolution any faster.  It just will cut
00176        * the already computed complete solution to the desired size!
00177        *
00178        * Default value: 0 (implying all eigenvalues will be computed)
00179        */
00180       int dimensions;
00181     };
00182 
00183 
00184     /**
00185      * Default constructor
00186      */
00187     symmetricEigenSystem();
00188 
00189     /**
00190      * Default constructor with parameters
00191      */
00192     symmetricEigenSystem(const parameters& params);
00193 
00194 
00195     /**
00196      * Calculate the Eigensystem with \a eigenvalues and \a eigenvalues
00197      * from the given data in \a theMatrix (Samples in rows). Due to the
00198      * symmetricity of the data it suffices if \a theMatrix is upper
00199      * triangular.
00200      *
00201      * @param theMatrix  Real symmetric matrix to be transformed.
00202      * Only the diagonal and above diagonal elements have
00203      * to be set.
00204      * @param eigenvalues  Elements will contain the eigenvalues.
00205      * @param eigenvectors Columns will contain the eigenvectors corresponding
00206      * to the eigenvalues.
00207      * returns true if successful, false otherwise.
00208      */
00209     virtual bool apply(const matrix<T>& theMatrix,
00210                        vector<T>& eigenvalues,
00211                        matrix<T>& eigenvectors) const;
00212 
00213 
00214     /**
00215      * Convenience function that calculates the Eigensystem like
00216      * apply, but uses the given argument \a dimensions instead of
00217      * those given in parameters::dimensions.
00218      *
00219      * @param theMatrix  Real symmetric matrix to be transformed.
00220      * Only the diagonal and above diagonal elements have
00221      * to be set.
00222      * @param eigenvalues  Elements will contain the eigenvalues.
00223      * @param eigenvectors Columns will contain the eigenvectors corresponding
00224      * to the eigenvalues.
00225      * @param dimensions number of dimensions in eigenspace
00226      * returns true if successful, false otherwise.
00227      */
00228     virtual bool reducedEigenSystem(const matrix<T>& theMatrix,
00229                                     vector<T>& eigenvalues,
00230                                     matrix<T>& eigenvectors,
00231                                     const int dimensions) const;
00232 
00233     /**
00234      * Returns the name of this class.
00235      */
00236     const std::string& name() const;
00237 
00238     /**
00239      * Returns a pointer to a clone of this functor.
00240      */
00241     virtual symmetricEigenSystem* clone() const;
00242 
00243     /**
00244      * Returns a pointer to a new instance of this functor.
00245      */
00246     virtual symmetricEigenSystem* newInstance() const;
00247 
00248     /**
00249      * returns the current parameters.
00250      */
00251     const parameters& getParameters() const;
00252 
00253   protected:
00254 #ifdef HAVE_LAPACK
00255   private:
00256     /**
00257      * Contained type in T
00258      * 
00259      * This is a trick of generic programming to be an alias of type T if it is
00260      * a normal type (double, float) or the contained type A if T is
00261      * complex<A>.
00262      */
00263     typedef typename typeInfo<T>::value_type value_type;
00264 
00265     inline void rotateT(T& g,T& h,matrix<T>& a,
00266                         const int i,const int j,const int k,const int l,
00267                         const T s,const T tau) const;
00268 
00269     inline void rotate(T& g,T& h,matrix<T>& a,
00270                        const int i,const int j,const int k,const int l,
00271                        const T s,const T tau) const;
00272 
00273 
00274     /**
00275      * Apply the LAPACK function with the correct parameters
00276      * 
00277      * The matrix \c theMatrix will be modified, since LAPACK uses the unused
00278       * triangular submatrix as buffer.
00279      */
00280     bool applyLapack(matrix<T>& theMatrix,
00281                      vector<T>& eigenvalues,
00282                      matrix<T>& eigenvectors,
00283                      const int dimensions) const;
00284     
00285     /**
00286      * Calls the lapack function of eigensystem of symmetric matrix
00287      * specialized for float and double
00288      */
00289     int evr(char* jobz, char* range, char* uplo,
00290             integer* n, T* a, integer* lda,
00291             value_type* vl, value_type* vu,
00292             integer* il, integer* iu,
00293             value_type* abstol,
00294             integer* m, value_type* w,
00295             T* z, integer* ldz, integer* isuppz,
00296             T* work, integer* lwork,
00297             value_type* rwork,integer* lrwork,
00298             integer* iwork, integer* liwork,
00299             integer* info) const;
00300 #endif
00301 
00302   };
00303 }
00304 
00305 
00306 #endif
00307 

Generated on Sun Sep 20 22:08:00 2009 for CVR-Lib by Doxygen 1.5.8