latest version v1.9 - last update 10 Apr 2010 |
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 .......: ltiVarianceFunctor.h 00027 * authors ....: Jochen Wickel 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 25.9.2000 00030 * revisions ..: $Id: ltiVarianceFunctor.h,v 1.11 2006/02/08 12:52:27 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_VARIANCE_FUNCTOR_H_ 00034 #define _LTI_VARIANCE_FUNCTOR_H_ 00035 00036 #include "ltiStatisticsFunctor.h" 00037 #include "ltiMeansFunctor.h" 00038 00039 namespace lti { 00040 /** 00041 * Functor which computes several kinds of variances for 00042 * vectors and matrices. 00043 * 00044 * Be careful with the terms used here. If you have following matrix 00045 * 00046 * \code 00047 * | 5 6 10 2 | 00048 * | 1 -2 4 4 | 00049 * | 3 2 1 -3 | 00050 * \endcode 00051 * 00052 * The (empirical) varianceOfRows means the variance of all rows, 00053 * i.e. a row vector containing the sum of the square of difference 00054 * between each row vector and the mean vector of all rows, divided 00055 * by the number of rows minus 1. This is (4 8 21 13). 00056 * 00057 * The (empirical) varianceOfColumns means the variance of all columns, 00058 * i.e. a column vector containing the sum of the square of difference 00059 * between each column vector and the mean vector of all columns, divided 00060 * by the number of columns minus 1. This is (8.667 4.667 2)^T. 00061 * 00062 * The parameter parameters::rowWise indicates that the matrix will be 00063 * seen as a set of row vectors (if true), or column vectors (false). 00064 */ 00065 template <class T> class varianceFunctor : public statisticsFunctor { 00066 public: 00067 /** 00068 * the parameters for the class varianceFunctor 00069 */ 00070 class parameters : public statisticsFunctor::parameters { 00071 public: 00072 /** 00073 * Type of the variance 00074 */ 00075 enum eVarianceType { 00076 Empirical=0, /**< Empirical Variance: 00077 * \f[ \frac{1}{n-1} \sum_i^n (x_i - \mu)^2 \f] 00078 */ 00079 Maxlikely=1 /**< Maximum Likelihood Variance: 00080 * \f[ \frac{1}{n} \sum_i^n (x_i - \mu)^2 \f] 00081 */ 00082 }; 00083 00084 /** 00085 * default constructor 00086 */ 00087 parameters() 00088 : statisticsFunctor::parameters() { 00089 rowWise=true; 00090 type=Empirical; 00091 correlation=false; 00092 }; 00093 00094 /** 00095 * copy constructor 00096 * @param other the parameters object to be copied 00097 */ 00098 parameters(const parameters& other) 00099 : statisticsFunctor::parameters() { 00100 copy(other); 00101 }; 00102 00103 /** 00104 * destructor 00105 */ 00106 ~parameters() { 00107 }; 00108 00109 /** 00110 * returns name of this type 00111 */ 00112 const char* getTypeName() const { 00113 return "varianceFunctor::parameters"; 00114 }; 00115 00116 /** 00117 * copy the contents of a parameters object 00118 * @param other the parameters object to be copied 00119 * @return a reference to this parameters object 00120 */ 00121 parameters& copy(const parameters& other) { 00122 # ifndef _LTI_MSC_6 00123 // MS Visual C++ 6 is not able to compile this... 00124 statisticsFunctor::parameters::copy(other); 00125 # else 00126 // ...so we have to use this workaround. 00127 // Conditional on that, copy may not be virtual. 00128 statisticsFunctor::parameters& 00129 (statisticsFunctor::parameters::* p_copy) 00130 (const statisticsFunctor::parameters&) = 00131 statisticsFunctor::parameters::copy; 00132 (this->*p_copy)(other); 00133 # endif 00134 00135 rowWise=other.rowWise; 00136 type=other.type; 00137 correlation=other.correlation; 00138 00139 return *this; 00140 }; 00141 00142 # ifndef _LTI_MSC_6 00143 /** 00144 * write the parameters in the given ioHandler 00145 * @param handler the ioHandler to be used 00146 * @param complete if true (the default) the enclosing begin/end will 00147 * be also written, otherwise only the data block will be 00148 * written. 00149 * @return true if write was successful 00150 */ 00151 virtual bool write(ioHandler& handler,const bool complete=true) const 00152 # else 00153 /** 00154 * workaround for MS-VC bug. Never use this method directly, 00155 * use write() instead 00156 */ 00157 bool writeMS(ioHandler& handler,const bool complete=true) const 00158 # endif 00159 { 00160 bool b = true; 00161 if (complete) { 00162 b = handler.writeBegin(); 00163 } 00164 00165 if (b) { 00166 lti::write(handler,"rowWise",rowWise); 00167 if (type == Empirical) { 00168 lti::write(handler,"type","Empirical"); 00169 } else { 00170 lti::write(handler,"type","Maxlikely"); 00171 } 00172 lti::write(handler,"correlation",correlation); 00173 00174 } 00175 00176 # ifndef _LTI_MSC_6 00177 // This is the standard C++ code, which MS Visual C++ 6 is not 00178 // able to compile... 00179 b = b && statisticsFunctor::parameters::write(handler,false); 00180 # else 00181 bool (functor::parameters::* p_writeMS)(ioHandler&, 00182 const bool) const = 00183 functor::parameters::writeMS; 00184 b = b && (this->*p_writeMS)(handler,false); 00185 # endif 00186 00187 if (complete) { 00188 b = b && handler.writeEnd(); 00189 } 00190 00191 return b; 00192 } 00193 00194 # ifdef _LTI_MSC_6 00195 /** 00196 * write the parameters in the given ioHandler 00197 * @param handler the ioHandler to be used 00198 * @param complete if true (the default) the enclosing begin/end will 00199 * be also written, otherwise only the data block will be 00200 * written. 00201 * @return true if write was successful 00202 */ 00203 virtual bool write(ioHandler& handler, 00204 const bool complete = true) const { 00205 // ...we need this workaround to cope with another really 00206 // awful MSVC bug. 00207 return writeMS(handler,complete); 00208 } 00209 # endif 00210 00211 # ifndef _LTI_MSC_6 00212 /** 00213 * read the parameters from the given ioHandler 00214 * @param handler the ioHandler to be used 00215 * @param complete if true (the default) the enclosing begin/end will 00216 * be also read, otherwise only the data block will be read. 00217 * @return true if write was successful 00218 */ 00219 virtual bool read(ioHandler& handler,const bool complete = true) 00220 # else 00221 /** 00222 * workaround for MS-VC bug. Never use this method directly, 00223 * use read() instead 00224 */ 00225 bool readMS(ioHandler& handler,const bool complete=true) 00226 # endif 00227 { 00228 bool b = true; 00229 if (complete) { 00230 b = handler.readBegin(); 00231 } 00232 00233 if (b) { 00234 lti::read(handler,"rowWise",rowWise); 00235 00236 std::string str; 00237 00238 lti::read(handler,"type",str); 00239 if (str == "Empirical") { 00240 type = Empirical; 00241 } else { 00242 type = Maxlikely; 00243 } 00244 00245 lti::read(handler,"correlation",correlation); 00246 } 00247 00248 # ifndef _LTI_MSC_6 00249 // This is the standard C++ code, which MS Visual C++ 6 is not 00250 // able to compile... 00251 b = b && statisticsFunctor::parameters::read(handler,false); 00252 # else 00253 bool (functor::parameters::* p_readMS)(ioHandler&,const bool) = 00254 functor::parameters::readMS; 00255 b = b && (this->*p_readMS)(handler,false); 00256 # endif 00257 00258 if (complete) { 00259 b = b && handler.readEnd(); 00260 } 00261 00262 return b; 00263 } 00264 00265 # ifdef _LTI_MSC_6 00266 /** 00267 * read the parameters from the given ioHandler 00268 * @param handler the ioHandler to be used 00269 * @param complete if true (the default) the enclosing begin/end will 00270 * be also read, otherwise only the data block will be read. 00271 * @return true if write was successful 00272 */ 00273 virtual bool read(ioHandler& handler,const bool complete=true) { 00274 // ...we need this workaround to cope with another really awful MSVC 00275 // bug. 00276 return readMS(handler,complete); 00277 } 00278 # endif 00279 00280 00281 /** 00282 * returns a pointer to a clone of the parameters 00283 */ 00284 virtual functor::parameters* clone() const { 00285 return new parameters(*this); 00286 }; 00287 00288 /** 00289 * If this flag is true, the variance computation will be row-wise, i.e. 00290 * the result will contain a sum of the rows. This is much faster 00291 * than column-wise, since data do not have to be copied. 00292 * 00293 * Default value: true 00294 */ 00295 bool rowWise; 00296 00297 /** 00298 * The type of the variance computation. If type == empirical, 00299 * the empirical variance or covariance matrix is computed 00300 * (division by number of samples minus 1), otherwise, the 00301 * maximum likelihood estimator is computed (division by 00302 * number of samples). 00303 * 00304 * Default value: Empirical 00305 */ 00306 eVarianceType type; 00307 00308 /** 00309 * If this flag is true, the covariance matrix is normalized 00310 * to contain the correlation coefficients instead of the 00311 * covariances. 00312 * 00313 * Default value: false 00314 */ 00315 bool correlation; 00316 00317 }; 00318 00319 /** 00320 * default constructor */ 00321 varianceFunctor(); 00322 00323 /** 00324 * copy constructor 00325 * @param other the object to be copied 00326 */ 00327 varianceFunctor(const varianceFunctor& other); 00328 00329 /** 00330 * destructor 00331 */ 00332 virtual ~varianceFunctor(); 00333 00334 /** 00335 * returns the name of this type ("varianceFunctor") 00336 */ 00337 virtual const char* getTypeName() const; 00338 00339 /** 00340 * returns the variance of the current vector. 00341 * @param srcdest vector<T> with the source data. The result 00342 * will be left here too. 00343 * @result a reference to the <code>srcdest</code>. 00344 */ 00345 T apply(const vector<T>& srcdest) const; 00346 00347 /** 00348 * computes the variance of the given vector. 00349 * @param src vector<T> with the source data. 00350 * @param dest vector<T> where the result will be left. 00351 * @result a reference to the <code>dest</code>. 00352 */ 00353 T &apply(const vector<T>& src, T& dest) const; 00354 00355 /** 00356 * The result of this function depends on the value of 00357 * parameters.rowWise. If this parameter is true, the functor 00358 * will compute a vector, whose elements contain each the variance 00359 * of one column of the matrix (the computes the variance of the rows, 00360 * where each row is a data point in n-dimensional space. 00361 * if rowWise is false, the result vector contains the variance 00362 * of the columns of the matrix (each column a data point). 00363 * @param src matrix<T> with the source data. 00364 * @param dest vector<T> where the result will be left. 00365 * @result a reference to the <code>dest</code>. 00366 */ 00367 vector<T>& apply(const matrix<T>& src, vector<T>& dest) const; 00368 00369 /** 00370 * This function 00371 * will compute a vector, whose elements contain each the variance 00372 * of one column of the matrix (the computes the variance of the rows, 00373 * where each row is a data point in n-dimensional space). 00374 * @param src matrix<T> with the source data. 00375 * @param dest vector<T> where the result will be left. 00376 */ 00377 void varianceOfRows(const matrix<T>& src, vector<T>& dest) const; 00378 00379 /** 00380 * The result vector contains the variances 00381 * of the columns of the matrix (each column a data point). 00382 * @param src matrix<T> with the source data. 00383 * @param dest vector<T> where the result will be left. 00384 */ 00385 void varianceOfColumns(const matrix<T>& src, vector<T>& dest) const; 00386 00387 00388 /** 00389 * The result is the covariance of these two vectors. The vectors are 00390 * regarded as series of outcomes of a twodimensional random variable. 00391 * This function computes the covariance of both dimensions of the 00392 * variable. 00393 * @param a vector<T> with dimension one of the random variable. 00394 * @param b vector<T> with dimension two of the random variable. 00395 * @return covariance between a and b 00396 */ 00397 T covariance(const vector<T>& a, const vector<T>& b) const; 00398 00399 /** 00400 * This function 00401 * will compute a matrix which contains the covariance matrix 00402 * of the data points in the first matrix, if each row constitutes 00403 * a data point in n-dimensional space 00404 * @param src matrix<T> with the source data. 00405 * @param dest matrix<T> where the result will be left. 00406 */ 00407 void covarianceMatrixOfRows(const matrix<T> &src, matrix<T>& dest) const; 00408 00409 /** 00410 * This function 00411 * will compute a matrix which contains the covariance matrix 00412 * of the data points in the first matrix, if each row constitutes 00413 * a data point in n-dimensional space 00414 * @param src matrix<T> with the source data. 00415 * @param dest matrix<T> where the result will be left. 00416 * @param mu mean value of the data. 00417 */ 00418 void covarianceMatrixOfRows(const matrix<T>& src, 00419 matrix<T>& dest, 00420 vector<T>& mu) const; 00421 00422 /** 00423 * This function 00424 * will compute a matrix which contains the covariance matrix 00425 * of the data points in the first matrix, if each row constitutes 00426 * a data point in n-dimensional space. This is an older, slow 00427 * version which has been left here, because there are a few 00428 * rare cases when it is still somewhat faster than the new version. 00429 * @param src matrix<T> with the source data. 00430 * @param dest matrix<T> where the result will be left. 00431 */ 00432 void slowCovarianceMatrixOfRows(const matrix<T> &src, matrix<T>& dest) const; 00433 00434 /** 00435 * This function 00436 * will compute a matrix which contains the covariance matrix 00437 * of the data points in the first matrix, if each column constitutes 00438 * a data point in n-dimensional space 00439 * @param src matrix<T> with the source data. 00440 * @param dest matrix<T> where the result will be left. 00441 */ 00442 void covarianceMatrixOfColumns(const matrix<T> &src,matrix<T>& dest) const; 00443 00444 /** 00445 * This function 00446 * will compute a matrix which contains the covariance matrix 00447 * of the data points in the first matrix, if each column constitutes 00448 * a data point in n-dimensional space 00449 * @param src matrix<T> with the source data. 00450 * @param dest matrix<T> where the result will be left. 00451 * @param mu mean value of the data. 00452 */ 00453 void covarianceMatrixOfColumns(const matrix<T> &src, 00454 matrix<T>& dest, 00455 vector<T>& mu) const; 00456 00457 00458 /** 00459 * copy data of "other" functor. 00460 * @param other the functor to be copied 00461 * @return a reference to this functor object 00462 */ 00463 varianceFunctor& copy(const varianceFunctor& other); 00464 00465 /** 00466 * returns a pointer to a clone of this functor. 00467 */ 00468 virtual functor* clone() const; 00469 00470 /** 00471 * returns used parameters 00472 */ 00473 const parameters& getParameters() const; 00474 00475 /** 00476 * Converts a covariance matrix into a correlation coefficient matrix. 00477 */ 00478 static void covar2corrcoef(matrix<T>& cv); 00479 00480 private: 00481 meansFunctor<T> mean; 00482 00483 }; 00484 } 00485 00486 00487 #endif