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

ltiLinearRegression.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  * project ....: LTI Digital Image/Signal Processing Library
00025  * file .......: ltiLinearRegression.h
00026  * authors ....: Holger Fillbrandt
00027  * organization: LTI, RWTH Aachen
00028  * creation ...: 4.7.2003
00029  * revisions ..: $Id: ltiLinearRegression.h,v 1.7 2006/02/08 12:31:41 ltilib Exp $
00030  */
00031 
00032 
00033 #ifndef _LTI_LINEAR_REGRESSION_H_
00034 #define _LTI_LINEAR_REGRESSION_H_
00035 
00036 #include "ltiLinearAlgebraFunctor.h"
00037 #include "ltiEigenSystem.h"
00038 #include "ltiIoHandler.h"
00039 
00040 #ifdef HAVE_LAPACK
00041 #include "ltiFastEigenSystem.h"
00042 #endif
00043 
00044 namespace lti {
00045   /**
00046    * The linear regression algorithm estimates a linear relation between
00047    * two vector spaces. To each vector <code>srcVect</code> of the source vector space with
00048    * dimension <code>srcDim</code>, the corresponding vector <code>destDim</code> of the destination
00049    * vector space with dimension <code>destDim</code> can be calculated using the resulting
00050    * regression matrix R:
00051    *
00052    *                           destVect = R * srcVect.
00053    *
00054    * R is calculated from a training set of corresponding vectors in both spaces.
00055    * Note that <code>srcVect</code> = 0 can only result in <code>destVect</code> = 0, so it is important
00056    * to eliminate any offsets from both vector spaces before using this algorithm:
00057    *
00058    *              destVect = destVectMean + R * (srcVect - srcVectMean)
00059    *
00060    * For example application see ltiLinearRegressionTracking.
00061    *
00062    * @ingroup gLinearAlgebra
00063    */
00064   template <class T>
00065   class linearRegression : public linearAlgebraFunctor {
00066   public:
00067     /**
00068      * the parameters for the class linearRegression
00069      */
00070     class parameters : public linearAlgebraFunctor::parameters {
00071     public:
00072       /**
00073        * default constructor
00074        */
00075       parameters() 
00076         : linearAlgebraFunctor::parameters() {
00077 
00078         eigenSystemDim = 10; // dimensionality of eigensystem   
00079 
00080       }
00081 
00082       /**
00083        * copy constructor
00084        * @param other the parameters object to be copied
00085        */
00086       parameters(const parameters& other) 
00087         : linearAlgebraFunctor::parameters() {
00088         copy(other);
00089       }
00090 
00091 
00092       /**
00093        * destructor
00094        */
00095       ~parameters(){
00096       }
00097 
00098       /**
00099        * returns name of this type
00100        */
00101       const char* getTypeName() const {
00102         return "linearRegression::parameters";
00103       }
00104 
00105       /**
00106        * copy the contents of a parameters object
00107        * @param other the parameters object to be copied
00108        * @return a reference to this parameters object
00109        */
00110       parameters& copy(const parameters& other) {
00111 #     ifndef _LTI_MSC_6
00112         // MS Visual C++ 6 is not able to compile this...
00113         linearAlgebraFunctor::parameters::copy(other);
00114 #     else
00115         // ...so we have to use this workaround.
00116         // Conditional on that, copy may not be virtual.
00117         functor::parameters&
00118           (functor::parameters::* p_copy)
00119           (const functor::parameters&) =
00120           functor::parameters::copy;
00121         (this->*p_copy)(other);
00122 #     endif
00123 
00124         eigenSystemDim=other.eigenSystemDim;
00125 
00126         return *this;
00127       }
00128 
00129 
00130       /**
00131        * Assigns the contents of the other object to this object
00132        */
00133       inline parameters& operator=(const parameters& other) {
00134         copy(other);
00135         return *this;
00136       }
00137 
00138       /**
00139        * returns a pointer to a clone of the parameters
00140        */
00141       virtual functor::parameters* clone() const {
00142         return new parameters(*this);
00143       }
00144 
00145 #     ifndef _LTI_MSC_6
00146       /**
00147        * read the parameters from the given ioHandler
00148        * @param handler the ioHandler to be used
00149        * @param complete if true (the default) the enclosing begin/end will
00150        *        be also read, otherwise only the data block will be read.
00151        * @return true if write was successful
00152        */
00153       virtual bool read(ioHandler &handler, const bool complete=true)
00154 #     else
00155       bool readMS(ioHandler& handler,const bool complete=true)
00156 #     endif
00157       {
00158         bool b=true;
00159 
00160         if (complete) {
00161           b=handler.readBegin();
00162         }
00163 
00164         if (b) {
00165           lti::read(handler,"eigenSystemDim",eigenSystemDim);
00166         }
00167 
00168 #     ifndef _LTI_MSC_6
00169         // This is the standard C++ code, which MS Visual C++ 6 is not
00170         // able to compile...
00171         b = b && linearAlgebraFunctor::parameters::read(handler,false);
00172 #     else
00173         bool (functor::parameters::* p_readMS)(ioHandler&,const bool) =
00174           functor::parameters::readMS;
00175         b = b && (this->*p_readMS)(handler,false);
00176 #     endif
00177 
00178         if (complete) {
00179           b=b && handler.readEnd();
00180         }
00181 
00182         return b;
00183       }
00184 
00185 #     ifdef _LTI_MSC_6
00186       /**
00187        * read the parameters from the given ioHandler
00188        * @param handler the ioHandler to be used
00189        * @param complete if true (the default) the enclosing begin/end will
00190        *        be also read, otherwise only the data block will be read.
00191        * @return true if write was successful
00192        */
00193       virtual bool read(ioHandler& handler,const bool complete=true) {
00194         // ...we need this workaround to cope with another really awful MSVC
00195         // bug.
00196         return readMS(handler,complete);
00197       }
00198 #     endif
00199 
00200 #     ifndef _LTI_MSC_6
00201       /**
00202        * write the parameters in the given ioHandler
00203        * @param handler the ioHandler to be used
00204        * @param complete if true (the default) the enclosing begin/end will
00205        *        be also written, otherwise only the data block will be
00206        *        written.
00207        * @return true if write was successful
00208        */
00209       virtual bool write(ioHandler& handler,const bool complete=true) const
00210 #     else
00211       bool writeMS(ioHandler& handler,const bool complete=true) const
00212 #     endif
00213       {
00214         bool b=true;
00215 
00216         if (complete) {
00217           b=handler.writeBegin();
00218         }
00219 
00220         if (b) {
00221           lti::write(handler,"eigenSystemDim",eigenSystemDim);
00222 
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 && linearAlgebraFunctor::parameters::write(handler,false);
00229 #       else
00230         bool
00231         (functor::parameters::* p_writeMS)(ioHandler&,const bool) const =
00232           functor::parameters::writeMS;
00233         b = b && (this->*p_writeMS)(handler,false);
00234 #       endif
00235 
00236         if (complete) {
00237           b=b && handler.writeEnd();
00238         }
00239 
00240         return b;
00241       }
00242 
00243 #     ifdef _LTI_MSC_6
00244       /**
00245        * write the parameters to 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 writen, otherwise only the data block will be writen.
00249        * @return true if write was successful
00250        */
00251       virtual bool write(ioHandler& handler,const bool complete=true) {
00252         // ...we need this workaround to cope with another really awful MSVC
00253         // bug.
00254         return writeMS(handler,complete);
00255       }
00256 #     endif
00257 
00258       /**
00259        * Dimensionality of the eigensystem which is constructed
00260        * during calculation of the linear regression matrix.
00261        * It must not be bigger than the number of trainingvectors used.
00262        *  The quality of the resulting matrix depends on this value, it should
00263        * be neither to small nor to big. There are methods to estimate the
00264        * optimal value in the literature, but none has been implemented 
00265        * in this functor yet. The default is 10.
00266        */
00267       int eigenSystemDim;
00268 
00269 
00270     };
00271 
00272     /**
00273      * default constructor
00274      */
00275     linearRegression();
00276 
00277     /**
00278      * default constructor with parameters
00279      * 
00280      */
00281     linearRegression(const parameters& par);
00282 
00283     /**
00284      * copy constructor
00285      * @param other the object to be copied
00286      */
00287     linearRegression(const linearRegression& other);
00288 
00289     /**
00290      * destructor
00291      */
00292     virtual ~linearRegression();
00293 
00294     /**
00295      * returns the name of this type ("linearRegression")
00296      */
00297     virtual const char* getTypeName() const;
00298 
00299     /**
00300      * The linear regression algorithm. It calculates a linear transformation
00301      * matrix linRegMatrix, that approximately fulfills
00302      * destMatrix = linRegMatrix * srcMatrix.
00303      * @param srcMatrix the columns of this matrix are the source training vectors of dimension srcDim
00304      * @param destMatrix the columns of this matrix are the destination training vectors of dimension destDim
00305      * @return resulting (destDim x srcDim) transformation matrix. This is also kept in the parameter linRegMatrix and can be used directly with "transform"
00306      */
00307     matrix<T> apply(matrix<T>& srcMatrix, matrix<T>& destMatrix);
00308 
00309     /**
00310      * multiplication of srcVector with the linear regression matrix
00311      * of dimension (destDim x srcDim)
00312      * @param srcVector source vector of dimension srcDim
00313      * @param destVector destination vector of dimension destDim
00314      */
00315     void transform(vector<T>& srcVector, vector<T>& destVector) const;
00316 
00317     /**
00318      * multiplication of srcVector with the linear regression matrix
00319      * of dimension (destDim x srcDim)
00320      * @param srcVector source vector of dimension srcDim
00321      * @return destination vector of dimension destDim
00322      */
00323     vector<T> transform(vector<T>& srcVector) const;
00324 
00325     /**
00326      * gets the linear regression matrix
00327      */
00328     matrix<T> getLinRegMatrix() const;
00329 
00330     /**
00331      * sets the linear regression matrix
00332      */
00333     void setLinRegMatrix(matrix<T> &linRegMatrixSet);
00334 
00335     /**
00336      * copy data of "other" functor.
00337      * @param other the functor to be copied
00338      * @return a reference to this functor object
00339      */
00340     linearRegression& copy(const linearRegression& other);
00341 
00342     /**
00343      * Alias for copy.
00344      */
00345     linearRegression& operator=(const linearRegression& other);
00346 
00347     /**
00348      * returns a pointer to a clone of this functor.
00349      */
00350     virtual functor* clone() const;
00351 
00352     /**
00353      * returns used parameters
00354      */
00355     const parameters& getParameters() const;
00356 
00357 
00358     /**
00359      * Reads this functor from the given handler.
00360      */
00361     virtual bool read(ioHandler &handler, const bool complete=true);
00362 
00363     /**
00364      * Writes this functor to the given handler.
00365      */
00366     virtual bool write(ioHandler &handler, const bool complete=true) const;
00367 
00368     protected:
00369     matrix<T> linRegMatrix;
00370 
00371   };
00372 
00373   template <class T>
00374   bool read(ioHandler& handler,
00375             linearRegression<T>& linReg,
00376             const bool complete=true) {
00377     return linReg.read(handler,complete);
00378   }
00379 
00380 
00381   template <class T>
00382   bool write(ioHandler& handler,
00383              const linearRegression<T>& linReg,
00384              const bool complete=true) {
00385     return linReg.write(handler,complete);
00386   }
00387 
00388 }
00389 
00390 #endif

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