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

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

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