latest version v1.9 - last update 10 Apr 2010 |
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