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-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiChiSquareFunctor.h 00027 * authors ....: Birgit Gehrke 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 3.6.2002 00030 * revisions ..: $Id: ltiChiSquareFunctor.h,v 1.8 2006/02/08 12:13:54 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_CHI_SQUARE_FUNCTOR_H_ 00034 #define _LTI_CHI_SQUARE_FUNCTOR_H_ 00035 00036 00037 // Check this include to parent class: 00038 #include <ltiFunctor.h> 00039 #include "ltiVector.h" 00040 #include <list> 00041 #include <vector> 00042 #include <string> 00043 #include "ltiSerialStatsFunctor.h" 00044 00045 namespace lti { 00046 00047 /** 00048 * chiSquareFunctor calculates the chiSquareValue indicating the 00049 * likelihood, that the considerd elements are drawn from a 00050 * gaussian normal distribution. 00051 * 00052 * All results are written to the file chiSquareInfo.txt (the use may 00053 * specify another name for this file) 00054 * 00055 * the default parameter values are optimal for integer data 00056 * Mean and variance of the distribution are drawn from the data 00057 * if the user has not specified other values. 00058 * 00059 * For a similar algorithm of the Chi-Square Test and numerical 00060 * integration see "Numerical Recipes in C (Cambridge University 00061 * Press)" 00062 * 00063 * example: 00064 * \code 00065 * 00066 * double data[] = {2,5,6,7.5,8,9,7,6,5,4,3}; 00067 * lti::vector<double> vct(11,data); 00068 * 00069 * double chiSquare; 00070 * lti::chiSquareFunctor csf; 00071 * 00072 * lti::chiSquareFunctor::parameters param; // set a parameter 00073 * param.minimalWidth = 0.5; 00074 * csf.setParameters(param); 00075 * 00076 * csf.consider(vct); 00077 * csf.apply(chiSquare); 00078 * 00079 * std::cout << "chiSquare: " << chiSquare << std::endl; 00080 * std::cout << "numberOfIntervalls: " 00081 * << csf.getNumberOfIntervalls() << std::endl; 00082 * std::cout << csf.getStatusString() << std::endl;// gives information 00083 * // when an error ocurred 00084 * 00085 * \endcode 00086 */ 00087 class chiSquareFunctor : public functor { 00088 public: 00089 /** 00090 * the parameters for the class chiSquareFunctor 00091 */ 00092 class parameters : public functor::parameters { 00093 public: 00094 00095 /** 00096 * default constructor 00097 */ 00098 parameters(); 00099 00100 /** 00101 * copy constructor 00102 * @param other the parameters object to be copied 00103 */ 00104 parameters(const parameters& other); 00105 00106 /** 00107 * destructor 00108 */ 00109 ~parameters(); 00110 00111 /** 00112 * returns name of this type 00113 */ 00114 const char* getTypeName() const; 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 00123 /** 00124 * copy the contents of a parameters object 00125 * @param other the parameters object to be copied 00126 * @return a reference to this parameters object 00127 */ 00128 parameters& operator=(const parameters& other); 00129 00130 00131 /** 00132 * returns a pointer to a clone of the parameters 00133 */ 00134 virtual functor::parameters* clone() const; 00135 00136 /** 00137 * write the parameters in the given ioHandler 00138 * @param handler the ioHandler to be used 00139 * @param complete if true (the default) the enclosing begin/end will 00140 * be also written, otherwise only the data block will be written. 00141 * @return true if write was successful 00142 */ 00143 virtual bool write(ioHandler& handler,const bool complete=true) const; 00144 00145 /** 00146 * read the parameters from the given ioHandler 00147 * @param handler the ioHandler to be used 00148 * @param complete if true (the default) the enclosing begin/end will 00149 * be also written, otherwise only the data block will be written. 00150 * @return true if write was successful 00151 */ 00152 virtual bool read(ioHandler& handler,const bool complete=true); 00153 00154 # ifdef _LTI_MSC_6 00155 /** 00156 * this function is required by MSVC only, as a workaround for a 00157 * very awful bug, which exists since MSVC V.4.0, and still by 00158 * V.6.0 with all bugfixes (so called "service packs") remains 00159 * there... This method is also public due to another bug, so please 00160 * NEVER EVER call this method directly: use read() instead 00161 */ 00162 bool readMS(ioHandler& handler,const bool complete=true); 00163 00164 /** 00165 * this function is required by MSVC only, as a workaround for a 00166 * very awful bug, which exists since MSVC V.4.0, and still by 00167 * V.6.0 with all bugfixes (so called "service packs") remains 00168 * there... This method is also public due to another bug, so please 00169 * NEVER EVER call this method directly: use write() instead 00170 */ 00171 bool writeMS(ioHandler& handler,const bool complete=true) const; 00172 # endif 00173 00174 // ------------------------------------------------ 00175 // the parameters 00176 // ------------------------------------------------ 00177 00178 //TODO: comment the parameters of your functor 00179 // If you add more parameters manually, do not forget to do following: 00180 // 1. indicate in the default constructor the default values 00181 // 2. make sure that the copy member also copy your new parameters 00182 // 3. make sure that the read and write members also read and 00183 // write your parameters 00184 00185 00186 /** 00187 * the accuracy for the integration of the gauss function. 00188 * small values lead to a good approximation 00189 * 00190 * default is 1.0e-5, reasonable values are 1.0e-10...infinite 00191 * if the user sets a value smaller than 1.0e-10, accuracy is set to 1.0e-10 00192 * small values cause very long calculations 00193 */ 00194 double accuracy; 00195 00196 /** 00197 * must allways be "true" if you have discrete data, 00198 * otherwise the Chi-Square Test won't work properly. 00199 * 00200 * default is true, because it does no harm except that it 00201 * constrains the intervall size to be multiple of minimum data distance 00202 */ 00203 bool discrete; 00204 00205 /** 00206 * true means that all intervalls will have the same size 00207 * 00208 * equidistant is not good for data with small and large distances 00209 * between the elements, because there may be intervalls which contain 00210 * no elements 00211 * 00212 * default is false 00213 */ 00214 bool equidistant; 00215 00216 /** 00217 * data is splitted in maxNumofIntervalls, than the number of intervalls 00218 * is reduced untill constraints are met 00219 * 00220 * maxNumberOfIntervalls must not be smaller than 3 00221 * default is 100; 00222 */ 00223 int maxNumOfIntervalls; 00224 00225 /** 00226 * the maximum number of steps for the integration; 00227 * integration is stopped after maxSteps even if accuracy is not reached 00228 * 00229 * default is 10, reasonable values are 5...15 00230 * 00231 * if the user sets a value smaller than 5, maxSteps is set to 5 00232 * if the user sets a vlaue larger than 15, maxSteps is set to 15 00233 * 00234 * be careful with large values, because it may take very long time 00235 * as long as accuracy is not reached, the integration intervall is 00236 * devided into more and more intervalls up to 2^maxSteps intevalls 00237 */ 00238 int maxSteps; 00239 00240 /** 00241 * the user may give the estimated mean of the data 00242 * 00243 * if no value is specified, mean of data is calculated 00244 * by lti::SerialStatsFunctor and this value is used for 00245 * the calculation of the chiSquare test 00246 * 00247 * default is numeric_limit<double> 00248 */ 00249 double mean; 00250 00251 /** 00252 * the minimal width of an intervall 00253 * 00254 * if the parameter minimalWidth is not explicitly set (i.e. 00255 * left at default value < 0), minimalWidth is set to the 00256 * smallest distance of the given data 00257 */ 00258 double minimalWidth; 00259 00260 /** 00261 * file contains information about the parameters, status and errors 00262 * default name: chiSquareInfo.txt 00263 */ 00264 std::string nameOfInfoFile; 00265 00266 /** 00267 * should the infoFile be saved? 00268 * default is true 00269 */ 00270 bool saveInfoFile; 00271 00272 /** 00273 * if useBetterMeanAndVar is true 00274 * mean and variance are calculated again after the intervalls were set 00275 * if all constraints are still met, this values will be used 00276 * if not an error is reported and the old values will be used 00277 * 00278 * default is true; 00279 */ 00280 bool useBetterMeanAndVar; 00281 00282 /** 00283 * the user may give the estimated variance of the data 00284 * 00285 * variance must be positive, if negative value is given absolute 00286 * of this value is used 00287 * 00288 * if no value is specified, variance of data is calculated 00289 * by lti::SerialStatsFunctor and this value is used for 00290 * the calculation of the chiSquare test 00291 * 00292 * default is numeric_limit<double> 00293 */ 00294 double variance; 00295 00296 }; 00297 00298 /** 00299 * default constructor 00300 */ 00301 chiSquareFunctor(); 00302 00303 /** 00304 * copy constructor 00305 * @param other the object to be copied 00306 */ 00307 chiSquareFunctor(const chiSquareFunctor& other); 00308 00309 /** 00310 * destructor 00311 */ 00312 virtual ~chiSquareFunctor(); 00313 00314 /** 00315 * returns the name of this type ("chiSquareFunctor") 00316 */ 00317 virtual const char* getTypeName() const; 00318 00319 /** 00320 * copy data of "other" functor. 00321 * @param other the functor to be copied 00322 * @return a reference to this functor object 00323 */ 00324 chiSquareFunctor& copy(const chiSquareFunctor& other); 00325 00326 /** 00327 * alias for copy member 00328 * @param other the functor to be copied 00329 * @return a reference to this functor object 00330 */ 00331 chiSquareFunctor& operator=(const chiSquareFunctor& other); 00332 00333 /** 00334 * returns a pointer to a clone of this functor. 00335 */ 00336 virtual functor* clone() const; 00337 00338 /** 00339 * returns used parameters 00340 */ 00341 const parameters& getParameters() const; 00342 00343 //TODO comment the attributes of your functor 00344 // If you add more attributes manually, do not forget to do following: 00345 // 1. indicate in the default constructor the default values 00346 // 2. make sure that the copy member also copy your new attributes, or 00347 // to ensure there, that these attributes are properly initialized. 00348 00349 00350 /** 00351 * considers one Element (adds it to intern element list) 00352 */ 00353 void consider(const double& element); 00354 00355 /** 00356 * considers one Element freq times (adds it to intern element list) 00357 * returns false if freq equals zero or has a negative value 00358 */ 00359 bool consider(const double& element, const int freq); 00360 00361 /** 00362 * considers each element of the vector (adds it to intern element list) 00363 * returns false if vector is empty 00364 */ 00365 bool consider(const lti::vector<double> element); 00366 00367 /** 00368 * considers the vector freq times (adds it to intern element list) 00369 * returns false if freq equals zero or has a negative value 00370 * or if vector is empty 00371 */ 00372 bool consider(const vector<double> element, const int freq); 00373 00374 /** 00375 * if apply function has not been called jet, 00376 * or maximal number of Intervalls was not specified: returns 100 00377 */ 00378 int getNumberOfIntervalls() const; 00379 00380 /** 00381 * result of Chi-Square test will be stored in chiSquare 00382 */ 00383 bool apply(double& chiSquare); 00384 00385 /** 00386 * returns the chiSquareValue, after the apply function has been called 00387 * if apply has not been called, getChiSqureValue returns negative -1.0; 00388 */ 00389 double getChiSquareValue(); 00390 00391 /** 00392 * to check the inhold of the elementList 00393 * elements are printed to standard output 00394 */ 00395 void showElementList(); 00396 00397 /** 00398 * deletes all elements from m_ElementList, intervallList 00399 * and intervallBorders 00400 */ 00401 void resetElements(); 00402 00403 /** 00404 * returns the variance of the given data 00405 * returns 0 if no data has been given before call of getVariance 00406 * does NOT return the variance the user specified 00407 * variance is calculated with lti::serialStatsFunctor 00408 */ 00409 double getVarianceOfData(); 00410 00411 /** 00412 * returns the mean of the given data 00413 * returns 0 if no data has been given before call of getMean 00414 * does NOT return the mean the user specified 00415 * mean is calculated with lti::serialStatsFunctor 00416 */ 00417 double getMeanOfData(); 00418 00419 00420 private: 00421 void writeOutputFile(); 00422 00423 /** 00424 * is called by setIntervalls 00425 * returns false if constraints could not be met 00426 */ 00427 bool combineIntervalls(int index, bool equidistant); 00428 00429 /** 00430 * calculates how many elements from the element list belong to 00431 * an intervall of the borderList 00432 * and stores result in intervallList 00433 */ 00434 void setIntervallVec(); 00435 00436 /** 00437 * calls integration function untill accuracy or maxSteps is reached 00438 * returns false if the given accuracy could not be reached in maxSteps 00439 */ 00440 bool integrationAccuracy(double lowBorder, double highBorder); 00441 00442 /** 00443 * returns the result of the gauss function 00444 */ 00445 double gaussFunc(double x); 00446 00447 /** 00448 * low and high border contain the intervall borders, integration 00449 * will stop when accuracy or maxSteps is reached; 00450 * depth increases with each call of the integration function 00451 * until maxSteps is reached; 00452 * the integration intervall is devided into 2^depth intervalls 00453 */ 00454 double integration(double lowBorder, double highBorder, int depth); 00455 00456 /** 00457 * calculates the chiSquare value and stores it in private variable 00458 * chiSquareValue 00459 */ 00460 void chiSquareCalc(); 00461 00462 /** 00463 * returns false if there is not enough data 00464 */ 00465 bool setIntervalls(bool equidistant); 00466 00467 /** 00468 * checks if string is allready in m_StringList, if not string is added 00469 */ 00470 void statusPushback(std::string status); 00471 00472 //------------------------------------------------------ 00473 // Variables 00474 //------------------------------------------------------ 00475 00476 /** 00477 * first it's maxNumOfInts, than it's reduced untill it meets the 00478 * constraints 00479 */ 00480 int m_NumberOfIntervalls; 00481 00482 /// value of the element with the m_Biggest value 00483 double m_Biggest; 00484 00485 /// value of the element with the m_Smallest value 00486 double m_Smallest; 00487 00488 /// m_Mean calculated with the serialStatsFunctor or set by user 00489 double m_Mean; 00490 00491 /// variance calculated with the serialStatsFunctor or set by user 00492 double m_Variance; 00493 00494 /// result of chiSquareCalc() 00495 double m_ChiSquareValue; 00496 00497 /// result of integrationAccuracy() 00498 double m_GaussIntegral; 00499 00500 /** 00501 * result of integration over all intervalls, to normalize value 00502 * of intervall to 1 00503 */ 00504 double m_Norm; 00505 00506 /// number of all elements which were considered 00507 double m_NumberOfElements; 00508 00509 /// calculated after intervalls were set 00510 double m_MeanIntervalls; 00511 00512 /// calculated after intervalls were set 00513 double m_VarianceIntervalls; 00514 00515 /// is true if it is possible to use better Mean and Var 00516 bool m_UseBetterMeanAndVar; 00517 00518 /// all results are written to this file 00519 std::string m_NameOfInfoFile; 00520 00521 /// for calculation of mean and variance 00522 lti::serialStatsFunctor<double> m_Stats; 00523 00524 /// changes during intervall setting 00525 std::vector<double> m_BordersVec; 00526 00527 /// contains the number of elements in each intervall 00528 std::vector<int> m_IntervallVec; 00529 00530 /// expected number of elements in an intervall 00531 std::vector<double> m_ExpectedVec; 00532 00533 /// contains all elements which were considered 00534 std::list<double> m_ElementList; 00535 00536 /** 00537 * all StatusStrings that were set, are stored here and later 00538 * written in infoFile 00539 */ 00540 std::list<std::string> m_StatusList; 00541 }; 00542 } 00543 00544 #endif