LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiChiSquareFunctor.h

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

Generated on Sat Apr 10 15:25:12 2010 for LTI-Lib by Doxygen 1.6.1