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

ltiVarianceFunctor.h

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

Generated on Sat Apr 10 15:26:22 2010 for LTI-Lib by Doxygen 1.6.1