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