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

ltiLDA.h

00001 /*
00002  * Copyright (C) 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 .......: ltiLDA.h
00027  * authors ....: Jochen Wickel
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 27.11.2000
00030  * revisions ..: $Id: ltiLDA.h,v 1.7 2006/02/07 18:05:36 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_L_D_A_H_
00034 #define _LTI_L_D_A_H_
00035 
00036 #include "ltiLapackInterface.h"
00037 
00038 #ifdef HAVE_LAPACK
00039 
00040 #include "ltiLinearAlgebraFunctor.h"
00041 #include "ltiMatrixInversion.h"
00042 #include "ltiGenEigVectors.h"
00043 #include "ltiMeansFunctor.h"
00044 #include "ltiVarianceFunctor.h"
00045 
00046 
00047 namespace lti {
00048   /**
00049    * Functor for computing a linear discriminant analysis (LDA).
00050    *
00051    * It uses functors that require the LAPack.
00052    *
00053    * @ingroup lapack
00054    *
00055    * @see \ref lapack
00056    */
00057   template <class T>
00058   class linearDiscriminantAnalysis : public linearAlgebraFunctor {
00059   public:
00060     /**
00061      * the parameters for the class linearDiscriminantAnalysis
00062      */
00063     class parameters : public linearAlgebraFunctor::parameters {
00064     public:
00065       /**
00066        * default constructor
00067        */
00068       parameters();
00069 
00070       /**
00071        * copy constructor
00072        * @param other the parameters object to be copied
00073        */
00074       parameters(const parameters& other);
00075 
00076       /**
00077        * destructor
00078        */
00079       ~parameters();
00080 
00081       /**
00082        * returns name of this type
00083        */
00084       const char* getTypeName() const;
00085 
00086       /**
00087        * copy the contents of a parameters object
00088        * @param other the parameters object to be copied
00089        * @return a reference to this parameters object
00090        */
00091       parameters& copy(const parameters& other);
00092 
00093       /**
00094        * returns a pointer to a clone of the parameters
00095        */
00096       virtual functor::parameters* clone() const;
00097 
00098       //TODO: comment the parameters of your functor
00099 
00100       virtual bool read(ioHandler &handler, const bool complete=true);
00101       virtual bool write(ioHandler &handler, const bool complete=true) const;
00102 
00103       /**
00104        * This is the dimension of the reduced vectors.
00105        */
00106       int resultDim;
00107 
00108       /**
00109        * This flag determines, if the functor should determine a
00110        * maximum allowable dimension itself. "Maximum dimension" means
00111        * that the dimension is equal to the number of eigenvalues of
00112        * the covariance matrix which are larger than zero.
00113        *
00114        * Default value: false
00115        */
00116       bool autoDim;
00117 
00118       /**
00119        * If true, singular value decomposition instead of LU
00120        * decomposition is used for inverting the Sw (within-class
00121        * scatter) matrix. This is much safer than the original method,
00122        * since it always computes a meaningful result: for singular
00123        * matrices, it computes the closest approximation.
00124        */
00125       bool useSVD;
00126     };
00127 
00128     /**
00129      * default constructor
00130      */
00131     linearDiscriminantAnalysis();
00132 
00133     /**
00134      * copy constructor
00135      * @param other the object to be copied
00136      */
00137     linearDiscriminantAnalysis(const linearDiscriminantAnalysis& other);
00138 
00139     /**
00140      * destructor
00141      */
00142     virtual ~linearDiscriminantAnalysis();
00143 
00144     /**
00145      * returns the name of this type ("linearDiscriminantAnalysis")
00146      */
00147     virtual const char* getTypeName() const;
00148 
00149     /**
00150      * operates on the given %parameter.
00151      * @param srcdest matrix<T> with the source data.  The result
00152      *                 will be left here too.
00153      * @param labels ivector for each row of the source matrix, this
00154      *        vector contains the class label.
00155      * @result true if the LDA could be computed, false otherwise
00156      */
00157     bool apply(matrix<T>& srcdest, const ivector& labels);
00158 
00159     /**
00160      * Computes the linear discriminant analysis for the data given in
00161      * src. It internally stores a transformation matrix which is applied
00162      * to the data. This matrix can be reused by calling one of the
00163      * functions without the label vector.
00164      *
00165      * @param src matrix<T> with the source data.
00166      * @param dest matrix<T> where the result will be left.
00167      * @param labels ivector for each row of the source matrix, this
00168      *        vector contains the class label.
00169      * @result true if the LDA could be computed, false otherwise
00170     */
00171     bool apply(const matrix<T>& src, matrix<T>& dest,
00172                const ivector& labels);
00173 
00174     /**
00175      * Computes a  linear discriminant analysis for the data given in
00176      * src. This matrix is assumed to contain the data points for
00177      * one class. The computed transformation is stored internally
00178      * and can be used just as a global transformation. The main
00179      * purpose of this method is to be used for LDA classifiers,
00180      * which compute class-wise LDA transforms and classify by
00181      * subsequently applying the LDA's of all classes to the vector, and
00182      * then choosing the class whose mean is closest to the presented
00183      * vector. This method can be used to compute the required LDAs.
00184      *
00185      * @param src matrix<T> with the source data.
00186      * @param dest matrix<T> where the result will be left.
00187      * @param Sb matrix<T> which is the between-class
00188      *        scatter matrix of the entire population.
00189      * @result true if the LDA could be computed, false otherwise
00190     */
00191     bool apply(const matrix<T>& src, matrix<T>& dest,
00192                const matrix<T>& Sb);
00193 
00194 
00195     /**
00196      * Uses a previously computed transform in order to reduce
00197      * the given data set's dimensionality according to the
00198      * resultDim parameter.
00199      * @param src matrix<T> with the source data.
00200      * @param result matrix<T> with the result data.
00201      * @result true if the LDA could be applied, false otherwise
00202      */
00203     bool apply(const matrix<T>&src, matrix<T>& result);
00204 
00205     /**
00206      * Uses a previously computed transform in order to reduce
00207      * the given data set's dimensionality according to the
00208      * resultDim parameter.
00209      * @param src matrix<T> with the source data.
00210      * @param result matrix<T> with the result data.
00211      * @result true if the LDA could be applied, false otherwise
00212      */
00213     bool apply(const vector<T>&src, vector<T>& result);
00214 
00215     /**
00216      * On-Place version of the transformation.
00217      * @param srcdest matrix<T> with the source data, which will also contain
00218      *        the result.
00219      * @result true if the LDA could be applied, false otherwise
00220      */
00221     bool apply(matrix<T>& srcdest);
00222 
00223     /**
00224      * Set the dimension to which the vectors should be reduced.
00225      */
00226     void setDimension(int k);
00227 
00228     /**
00229      * set functor's parameters.
00230      * This member makes a copy of <em>theParam</em>: the functor
00231      * will keep its own copy of the parameters!
00232      * The difference to the standard is that this one passes
00233      * the useSVD flag on to the matrix inverter.
00234      * @return true if successful, false otherwise
00235      */
00236     virtual bool setParameters(const parameters& theParam);
00237 
00238 
00239     /**
00240      * Returns the previously computed eigenvalues of the scatter
00241      * matrix.
00242      * @param result the vector which will receive the eigenvalues.
00243      * @return true if the values could be obtained, false otherwise.
00244      */
00245     bool getEigenValues(vector<T>& result) const;
00246 
00247     /**
00248      * Returns the previously computed eigenvalues of the scatter
00249      * matrix.
00250      * @return true if the values could be obtained, false otherwise.
00251      */
00252     const vector<T>& getEigenValues() const;
00253 
00254     /**
00255      * Returns the previously computed eigenvectors of the scatter
00256      * matrix.
00257      * @param result the matrix which will receive the eigenvectors.
00258      *        Each column of the matrix contains one eigenvector.
00259      * @return true if the vectors could be obtained, false otherwise
00260      */
00261     bool getEigenVectors(matrix<T>& result) const;
00262 
00263     /**
00264      * Returns the previously computed eigenvectors of the scatter
00265      * matrix.
00266      *
00267      * This method will call the normal getEigenVectors() methods and
00268      * after that will transpose the obtained matrix, i.e. it is faster
00269      * to get the eigenvectors in the columns.
00270      *
00271      * @param result the matrix which will receive the eigenvectors.
00272      *        Each row of the matrix contains one eigenvector.
00273      * @return true if the vectors could be obtained, false otherwise
00274      */
00275     bool getEigenVectorsInRows(matrix<T>& result) const;
00276 
00277     /**
00278      * copy data of "other" functor.
00279      * @param other the functor to be copied
00280      * @return a reference to this functor object
00281      */
00282     linearDiscriminantAnalysis& copy(const linearDiscriminantAnalysis& other);
00283 
00284     /**
00285      * returns a pointer to a clone of this functor.
00286      */
00287     virtual functor* clone() const;
00288 
00289     /**
00290      * returns used parameters
00291      */
00292     const parameters& getParameters() const;
00293 
00294     /**
00295      * Computes the between-class scatter matrix Sb.
00296      */
00297     bool computeSb(const matrix<T>& src, matrix<T>& Sb,
00298                    const ivector& labels) const;
00299 
00300     virtual bool read(ioHandler &handler, const bool complete=true);
00301     virtual bool write(ioHandler &handler, const bool complete=true) const;
00302 
00303     int getUsedDimension() const {
00304       return usedDimensionality;
00305     }
00306 
00307     bool getTransformMatrix(matrix<T>& result) const;
00308     const matrix<T>& getTransformMatrix() const;
00309     const matrix<T>& getEigenVectors() const;
00310 
00311   protected:
00312     void find(const ivector &data, int value, ivector &result) const;
00313 
00314     void submatrix(const matrix<T>& data,const ivector &index,
00315                    matrix<T>& result) const;
00316 
00317     /**
00318      * Determines the intrinsic dimensionality of the data set if the
00319      * user specify autoDim, otherwise return parameters::resultDim.
00320      * The member usedDimensionality will be set with the returned value
00321      */
00322     int checkDim();
00323 
00324     bool buildTransform(const matrix<T>& Sw, const matrix<T>& Sb);
00325 
00326   private:
00327     matrix<T> orderedEigVec;
00328     matrix<T> transformMatrix;
00329     vector<T> eigValues;
00330 
00331     matrixInversion<T> inv;
00332     varianceFunctor<T> var;
00333     varianceFunctor<T> mlvar;
00334     meansFunctor<T> mean;
00335     generalEigenVectors<T> eig;
00336 
00337 
00338     /**
00339      * dimensionality being used.
00340      */
00341     int usedDimensionality;
00342   };
00343 
00344 
00345   template <class T>
00346   bool read(ioHandler& handler, linearDiscriminantAnalysis<T>& pca, const bool complete=true) {
00347     return pca.read(handler,complete);
00348   }
00349 
00350 
00351   template <class T>
00352   bool write(ioHandler& handler, const linearDiscriminantAnalysis<T>& pca, const bool complete=true) {
00353     return pca.write(handler,complete);
00354   }
00355 
00356   template <class T>
00357     bool read(ioHandler& handler, typename linearDiscriminantAnalysis<T>::parameters& p, const bool complete=true) {
00358     return p.read(handler,complete);
00359   }
00360 
00361   template <class T>
00362     bool write(ioHandler& handler, typename linearDiscriminantAnalysis<T>::parameters& p, const bool complete=true) {
00363     return p.write(handler,complete);
00364   }
00365 
00366 
00367 }
00368 
00369 #endif
00370 #endif

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