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 .......: ltiMeansFunctor.h 00027 * authors ....: Jochen Wickel 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 25.9.2000 00030 * revisions ..: $Id: ltiSerialStatsFunctor.h,v 1.9 2006/05/03 10:02:13 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_SERIALSTATS_FUNCTOR_H_ 00034 #define _LTI_SERIALSTATS_FUNCTOR_H_ 00035 00036 #include "ltiVector.h" 00037 #include "ltiMatrix.h" 00038 #include "ltiStatisticsFunctor.h" 00039 00040 namespace lti { 00041 /** 00042 * Functor which computes several kinds of means for 00043 * vectors and matrices. It does NOT compute the extremes (min and max) of 00044 * the considered values, which is the main difference with his brother 00045 * functor lti::serialStatsFunctorExt 00046 * 00047 * The first template parameter T describes the type of the vectors 00048 * and matrices to be analysed. The second parameter U (usually the same 00049 * type as T) specify the type of the statistics. 00050 * 00051 * For example, if you want to compute the mean and variance of the 00052 * elements {2,5,6,7,9} with double precision, you can use following code: 00053 * 00054 * \code 00055 * 00056 * lti::serialStatsFunctor<double> stats; 00057 * double theAverage,theVariance; 00058 * double data[] = {2,5,6,7,9}; 00059 * lti::vector vct(5,data); 00060 * 00061 * stats.considerElements(vct); 00062 * stats.apply(theAverage,theVariance); 00063 * cout << "Average: " << theAverage << " Variance: " << theVariance << endl; 00064 * 00065 * \endcode 00066 * 00067 * It is also possible to compute the average/variance for each component 00068 * withing lti::vectors. 00069 00070 */ 00071 template <class T,class U=T> 00072 class serialStatsFunctor : public statisticsFunctor { 00073 public: 00074 /** 00075 * the parameters for the class meansFunctor 00076 */ 00077 class parameters : public statisticsFunctor::parameters { 00078 public: 00079 00080 /** 00081 * Type of the variance 00082 */ 00083 enum eVarianceType { 00084 Empirical=0, /**< Empirical */ 00085 Maxlikely=1 /**< Maxlikely */ 00086 }; 00087 00088 /** 00089 * default constructor 00090 */ 00091 parameters() : statisticsFunctor::parameters() { 00092 type = Empirical; 00093 }; 00094 00095 /** 00096 * copy constructor 00097 * @param other the parameters object to be copied 00098 */ 00099 parameters(const parameters& other) 00100 : statisticsFunctor::parameters() { 00101 copy(other); 00102 }; 00103 00104 /** 00105 * destructor 00106 */ 00107 ~parameters() {}; 00108 00109 /** 00110 * returns name of this type 00111 */ 00112 const char* getTypeName() const { 00113 return "serialStatsFunctor::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 type=other.type; 00136 00137 return *this; 00138 }; 00139 00140 /** 00141 * copy the contents of a parameters object 00142 * @param other the parameters object to be copied 00143 * @return a reference to this parameters object 00144 */ 00145 parameters& operator=(const parameters& other) { 00146 return copy(other); 00147 }; 00148 00149 /** 00150 * returns a pointer to a clone of the parameters 00151 */ 00152 virtual functor::parameters* clone() const { 00153 return new parameters(*this); 00154 }; 00155 00156 # ifndef _LTI_MSC_6 00157 /** 00158 * write the parameters in the given ioHandler 00159 * @param handler the ioHandler to be used 00160 * @param complete if true (the default) the enclosing begin/end will 00161 * be also written, otherwise only the data block will be 00162 * written. 00163 * @return true if write was successful 00164 */ 00165 virtual bool write(ioHandler& handler,const bool complete=true) const 00166 # else 00167 /** 00168 * workaround for MS-VC bug. Never use this method directly, 00169 * use write() instead 00170 */ 00171 bool writeMS(ioHandler& handler,const bool complete=true) const 00172 # endif 00173 { 00174 bool b = true; 00175 if (complete) { 00176 b = handler.writeBegin(); 00177 } 00178 00179 if (b) { 00180 if (type == Empirical) { 00181 lti::write(handler,"type","Empirical"); 00182 } else { 00183 lti::write(handler,"type","Maxlikely"); 00184 } 00185 } 00186 00187 # ifndef _LTI_MSC_6 00188 // This is the standard C++ code, which MS Visual C++ 6 is not 00189 // able to compile... 00190 b = b && statisticsFunctor::parameters::write(handler,false); 00191 # else 00192 bool (functor::parameters::* p_writeMS)(ioHandler&, 00193 const bool) const = 00194 functor::parameters::writeMS; 00195 b = b && (this->*p_writeMS)(handler,false); 00196 # endif 00197 00198 if (complete) { 00199 b = b && handler.writeEnd(); 00200 } 00201 00202 return b; 00203 } 00204 00205 # ifdef _LTI_MSC_6 00206 /** 00207 * write the parameters in the given ioHandler 00208 * @param handler the ioHandler to be used 00209 * @param complete if true (the default) the enclosing begin/end will 00210 * be also written, otherwise only the data block will be 00211 * written. 00212 * @return true if write was successful 00213 */ 00214 virtual bool write(ioHandler& handler, 00215 const bool complete = true) const { 00216 // ...we need this workaround to cope with another really 00217 // awful MSVC bug. 00218 return writeMS(handler,complete); 00219 } 00220 # endif 00221 00222 # ifndef _LTI_MSC_6 00223 /** 00224 * read the parameters from the given ioHandler 00225 * @param handler the ioHandler to be used 00226 * @param complete if true (the default) the enclosing begin/end will 00227 * be also read, otherwise only the data block will be read. 00228 * @return true if write was successful 00229 */ 00230 virtual bool read(ioHandler& handler,const bool complete = true) 00231 # else 00232 /** 00233 * workaround for MS-VC bug. Never use this method directly, 00234 * use read() instead 00235 */ 00236 bool readMS(ioHandler& handler,const bool complete=true) 00237 # endif 00238 { 00239 bool b = true; 00240 if (complete) { 00241 b = handler.readBegin(); 00242 } 00243 00244 if (b) { 00245 std::string str; 00246 00247 lti::read(handler,"type",str); 00248 if (str == "Empirical") { 00249 type = Empirical; 00250 } else { 00251 type = Maxlikely; 00252 } 00253 } 00254 00255 # ifndef _LTI_MSC_6 00256 // This is the standard C++ code, which MS Visual C++ 6 is not 00257 // able to compile... 00258 b = b && statisticsFunctor::parameters::read(handler,false); 00259 # else 00260 bool (functor::parameters::* p_readMS)(ioHandler&,const bool) = 00261 functor::parameters::readMS; 00262 b = b && (this->*p_readMS)(handler,false); 00263 # endif 00264 00265 if (complete) { 00266 b = b && handler.readEnd(); 00267 } 00268 00269 return b; 00270 } 00271 00272 # ifdef _LTI_MSC_6 00273 /** 00274 * read the parameters from the given ioHandler 00275 * @param handler the ioHandler to be used 00276 * @param complete if true (the default) the enclosing begin/end will 00277 * be also read, otherwise only the data block will be read. 00278 * @return true if write was successful 00279 */ 00280 virtual bool read(ioHandler& handler,const bool complete=true) { 00281 // ...we need this workaround to cope with another really awful MSVC 00282 // bug. 00283 return readMS(handler,complete); 00284 } 00285 # endif 00286 00287 00288 // ------------------------------------------------ 00289 // the parameters 00290 // ------------------------------------------------ 00291 00292 /** 00293 * The type of the variance computation. If type == empirical, 00294 * the empirical variance or covariance matrix is computed 00295 * (division by number of samples minus 1), otherwise, the 00296 * maximum likelihood estimator is computed (division by 00297 * number of samples). The default is empirical. 00298 */ 00299 eVarianceType type; 00300 00301 }; 00302 00303 /** 00304 * default constructor 00305 */ 00306 serialStatsFunctor(); 00307 00308 /** 00309 * copy constructor 00310 * @param other the object to be copied 00311 */ 00312 serialStatsFunctor(const serialStatsFunctor& other); 00313 00314 /** 00315 * destructor 00316 */ 00317 virtual ~serialStatsFunctor(); 00318 00319 /** 00320 * returns the name of this type ("serialStatsFunctor") 00321 */ 00322 virtual const char* getTypeName() const; 00323 00324 /** 00325 * returns mean and variance of the data elements considered so far. 00326 * @param mean the result, where the mean will be put 00327 * @param variance the result, where the variable will be put 00328 */ 00329 void apply(U& mean, U& variance) const; 00330 00331 /** 00332 * returns mean and variance vectors of the data vectors considered so far. 00333 * @param mean the result, where the mean will be put 00334 * @param variance the result, where the variable will be put 00335 */ 00336 void apply(vector<U>& mean, vector<U>& variance) const; 00337 00338 /** 00339 * This function considers the given element for computing the 00340 * mean and variance. 00341 */ 00342 void consider(const T &element); 00343 00344 /** 00345 * This function considers the given element for computing the 00346 * mean and variance as if it were presented n times. 00347 */ 00348 void consider(const T &element,const int& n); 00349 00350 /** 00351 * This function considers the given vector for computing the 00352 * mean and variance. 00353 */ 00354 void consider(const vector<T> &element); 00355 00356 /** 00357 * This function considers the given vector for computing the 00358 * mean and variance, as if it were presented n times. 00359 */ 00360 void consider(const vector<T> &element,const int& n); 00361 00362 /** 00363 * Consider also all elements of the given vector 00364 */ 00365 void considerElements(const vector<T> &elements); 00366 00367 /** 00368 * Consider also all elements of the given matrix 00369 */ 00370 void considerElements(const matrix<T> &elements); 00371 00372 /** 00373 * Consider also all elements of the given matrix which lie within 00374 * the given rectangle. 00375 */ 00376 void considerElements(const matrix<T> &elements,const rectangle& rect); 00377 00378 /** 00379 * Consider all rows of the given matrix as vectors 00380 */ 00381 void considerRows(const matrix<T> &elements); 00382 00383 /** 00384 * The mean of all elements that have been considered so far. 00385 */ 00386 U getMean() const; 00387 00388 /** 00389 * The variance of all elements that have been considered so far. 00390 */ 00391 U getVariance() const; 00392 00393 /** 00394 * The sum of all elements that have been considered so far. 00395 */ 00396 U getSumOfElements() const; 00397 00398 /** 00399 * The sum of the squares of of all elements that have been 00400 * considered so far. 00401 */ 00402 U getSumOfSquares() const; 00403 00404 /** 00405 * return the number of elements considered so far 00406 */ 00407 int getN() const; 00408 00409 /** 00410 * return the number of vectors considered so far 00411 */ 00412 int getNVectors() const; 00413 00414 /** 00415 * The mean of all vectors that have been considered so far. 00416 */ 00417 void getMean(vector<U> &m) const; 00418 00419 /** 00420 * The variance of all vectors that have been considered so far. 00421 */ 00422 void getVariance(vector<U> &v) const; 00423 00424 /** 00425 * The sum of all vectors that have been considered so far. 00426 * The values will be copied into the given vector. 00427 */ 00428 void getSumOfVectors(vector<U>& s) const; 00429 00430 /** 00431 * The sum of the squares of all vectors that have been considered 00432 * so far. 00433 * The values will be copied into the given vector. 00434 */ 00435 void getSumOfVectorSquares(vector<U>& s) const; 00436 00437 /** 00438 * The sum of all vectors that have been considered so far. 00439 * @return a read-only reference to the internal data 00440 */ 00441 const vector<U>& getSumOfVectors() const; 00442 00443 /** 00444 * The sum of the squares of all vectors that have been considered 00445 * so far. 00446 * @return a read-only reference to the internal data 00447 */ 00448 const vector<U>& getSumOfVectorSquares() const; 00449 00450 /** 00451 * Reset the series, i.e. discard all considered elements. 00452 */ 00453 void reset(); 00454 00455 /** 00456 * copy data of "other" functor. 00457 * @param other the functor to be copied 00458 * @return a reference to this functor object 00459 */ 00460 serialStatsFunctor& copy(const serialStatsFunctor& other); 00461 00462 /** 00463 * returns a pointer to a clone of this functor. 00464 */ 00465 virtual functor* clone() const; 00466 00467 /** 00468 * returns used parameters 00469 */ 00470 const parameters& getParameters() const; 00471 00472 private: 00473 U sumOfElements; 00474 U sumOfSquares; 00475 vector<U> sumOfVectors; 00476 vector<U> sumOfVecSq; 00477 int n; // number of elements considered so far 00478 int nv; // number of vector considered so far! 00479 }; 00480 } 00481 00482 #include "ltiSerialStatsFunctor_template.h" 00483 00484 #endif