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

ltiSerialVectorStats.h

00001 /*
00002  * Copyright (C) 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 ....: Suat Akyol
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 21.11.2001
00030  * revisions ..: $Id: ltiSerialVectorStats.h,v 1.10 2006/02/08 12:44:10 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_SERIALVECTORSTATS_H_
00034 #define _LTI_SERIALVECTORSTATS_H_
00035 
00036 #include "ltiVector.h"
00037 #include "ltiMatrix.h"
00038 #include "ltiStatisticsFunctor.h"
00039 #include "ltiTypeInfo.h"
00040 
00041 namespace lti {
00042   /**
00043    * Functor which computes the statistics of a series of vectors.
00044    * It delivers the mean vector and the covariance matrix, or
00045    * alternatively the variance vector under the assumption, that
00046    * the components of the vectors are independent from each other.
00047    *
00048    * If the empirical computation type is selected, the variances
00049    * resp. covariances will be normalized with (N-1). Otherwise
00050    * with N.
00051    *
00052    * An example (maximum-likelihood case, i.e. normalizing with N):
00053    *
00054    * Assume we have three vectors {3,4},{1,3},{2,2}
00055    *
00056    * The mean vector is {2,3}
00057    *
00058    * The covariance matrix, which is always symetric, is:
00059    *
00060    * \code
00061    * | 2/3  1/3  |
00062    * | 1/3  2/3  |
00063    * \endcode
00064    *
00065    * The variance vector is {2/3,2/3}, i.e. the diagonal elements
00066    * of the covariance matrix.
00067    */
00068   template <class T>
00069   class serialVectorStats : public statisticsFunctor {
00070   public:
00071     /**
00072      * the parameters for the class serialVectorStats
00073      */
00074     class parameters : public statisticsFunctor::parameters {
00075     public:
00076       
00077       /**
00078        * Type of the variance
00079        */
00080       enum eVarianceType {
00081         Empirical=0, /**< Empirical */
00082         Maxlikely=1  /**< Maxlikely */
00083       };
00084 
00085       /**
00086        * default constructor
00087        */
00088       parameters() : statisticsFunctor::parameters() {
00089         type = Empirical;
00090         correlation=false;
00091       };
00092 
00093       /**
00094        * copy constructor
00095        * @param other the parameters object to be copied
00096        */
00097       parameters(const parameters& other) 
00098         : statisticsFunctor::parameters() {
00099         copy(other);
00100       };
00101 
00102       /**
00103        * destructor
00104        */
00105       ~parameters() {};
00106 
00107       /**
00108        * returns name of this type
00109        */
00110       const char* getTypeName() const {
00111         return "serialVectorStats::parameters";
00112       };
00113 
00114       /**
00115        * copy the contents of a parameters object
00116        * @param other the parameters object to be copied
00117        * @return a reference to this parameters object
00118        */
00119       parameters& copy(const parameters& other) {
00120 #       ifndef _LTI_MSC_6
00121         // MS Visual C++ 6 is not able to compile this...
00122         statisticsFunctor::parameters::copy(other);
00123 #       else
00124         // ...so we have to use this workaround.
00125         // Conditional on that, copy may not be virtual.
00126         statisticsFunctor::parameters&
00127           (statisticsFunctor::parameters::* p_copy)
00128           (const statisticsFunctor::parameters&) =
00129           statisticsFunctor::parameters::copy;
00130         (this->*p_copy)(other);
00131 #      endif
00132 
00133         type=other.type;
00134         correlation=other.correlation;
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           lti::write(handler, "correlation", correlation);
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           lti::read(handler, "correlation", correlation);
00254         }
00255 
00256 #     ifndef _LTI_MSC_6
00257         // This is the standard C++ code, which MS Visual C++ 6 is not
00258         // able to compile...
00259         b = b && statisticsFunctor::parameters::read(handler,false);
00260 #     else
00261         bool (functor::parameters::* p_readMS)(ioHandler&,const bool) =
00262           functor::parameters::readMS;
00263         b = b && (this->*p_readMS)(handler,false);
00264 #     endif
00265 
00266         if (complete) {
00267           b = b && handler.readEnd();
00268         }
00269 
00270         return b;
00271       }
00272 
00273 #     ifdef _LTI_MSC_6
00274       /**
00275        * read the parameters from the given ioHandler
00276        * @param handler the ioHandler to be used
00277        * @param complete if true (the default) the enclosing begin/end will
00278        *        be also read, otherwise only the data block will be read.
00279        * @return true if write was successful
00280        */
00281       virtual bool read(ioHandler& handler,const bool complete=true) {
00282         // ...we need this workaround to cope with another really awful MSVC
00283         // bug.
00284         return readMS(handler,complete);
00285       }
00286 #     endif
00287 
00288 
00289       // ------------------------------------------------
00290       // the parameters
00291       // ------------------------------------------------
00292 
00293       /**
00294        * The type of the variance computation. If type == empirical,
00295        * the empirical variance or covariance matrix is computed
00296        * (division by number of samples minus 1), otherwise, the
00297        * maximum likelihood estimator is computed (division by
00298        * number of samples). 
00299        *
00300        * Default is Empirical.
00301        */
00302       eVarianceType type;
00303 
00304       /**
00305        * If true, the covariance function computes the correlation
00306        * coefficient instead.
00307        *
00308        * Default value: false
00309        */
00310       bool correlation;
00311     };
00312 
00313     typedef typename typeInfo<T>::square_accumulation_type sqrType;
00314 
00315     /**
00316      * default constructor
00317      */
00318     serialVectorStats();
00319     
00320     /**
00321      * copy constructor
00322      * @param other the object to be copied
00323      */
00324     serialVectorStats(const serialVectorStats& other);
00325 
00326     /**
00327      * destructor
00328      */
00329     virtual ~serialVectorStats();
00330 
00331     /**
00332      * returns the name of this type ("serialVectorStats")
00333      */
00334     virtual const char* getTypeName() const;
00335 
00336     /**
00337      * returns mean and variance vectors of the data vectors considered so far.
00338      * @param mean the result, where the mean will be put
00339      * @param variance the result, where the variance will be put
00340      */
00341     void apply(vector<T>& mean, vector<T>& variance) const;
00342 
00343     /**
00344      * returns mean vector and covariance matrix of the data vectors
00345      * considered so far.
00346      *
00347      * @param mean the result, where the mean will be put
00348      * @param covariance the matrix, where the covariances will be put
00349      */
00350     void apply(vector<T>& mean, matrix<T>& covariance) const;
00351 
00352     /**
00353      * This function considers the row vectors of the given matrix
00354      * for computing the mean and variance.
00355      */
00356     void considerRows(const matrix<T> &element);
00357 
00358     /**
00359      * This function considers the given vector for computing the
00360      * mean and variance.
00361      */
00362     void consider(const vector<T> &element);
00363 
00364     /**
00365      * This function considers the given vector for computing the
00366      * mean and variance, as if it were presented n times.
00367      */
00368     void consider(const vector<T> &element,const int& n);
00369 
00370     /**
00371      * return the number of elements considered so far
00372      */
00373     double getN() const;
00374 
00375     /**
00376      * set the number of elements considered so far
00377      */
00378     void setN(double newN);
00379 
00380     /**
00381      * The mean of all vectors that have been considered so far.
00382      */
00383     void getMean(vector<T> &mean) const;
00384 
00385     /**
00386      * The variance of all vectors that have been considered so far.
00387      */
00388     void getVariance(vector<T> &var) const;
00389 
00390     /**
00391      * The covariance of all vectors that have been considered so far.
00392      */
00393     void getCovariance(matrix<T> &covar) const;
00394 
00395     /**
00396      * The sum of all vectors that have been considered so far.
00397      * The values will be copied into the given vector.
00398      */
00399     void getSumOfVectors(vector<T>& s) const;
00400 
00401     /**
00402      * The sum of the squares of all vectors that have been considered
00403      * so far.
00404      * The values will be copied into the given vector.
00405      */
00406     void getSumOfVecOuterProd(matrix<sqrType>& s) const;
00407 
00408     /**
00409      * The sum of all vectors that have been considered so far.
00410      * @return a read-only reference to the internal data
00411      */
00412     const vector<T>& getSumOfVectors() const;
00413 
00414     /**
00415      * The sum of the outer products of all vectors that
00416      * have been considered so far. (i.e. sum(vec*vecTransposed))
00417      * @return a read-only reference to the internal data
00418      */
00419     const matrix<sqrType>& getSumOfVecOuterProd() const;
00420 
00421     /**
00422      * Reset the series, i.e. discard all considered elements.
00423      */
00424     void reset();
00425 
00426     /**
00427      * copy data of "other" functor.
00428      * @param other the functor to be copied
00429      * @return a reference to this functor object
00430      */
00431     serialVectorStats& copy(const serialVectorStats& other);
00432 
00433     /**
00434      * Alias for copy.
00435      */
00436     serialVectorStats& operator=(const serialVectorStats& other);
00437 
00438     /**
00439      * returns a pointer to a clone of this functor.
00440      */
00441     virtual functor* clone() const;
00442 
00443     /**
00444      * returns used parameters
00445      */
00446     const parameters& getParameters() const;
00447 
00448     /**
00449      * Reads this functor from the given handler.
00450      */
00451     virtual bool read(ioHandler &handler, const bool complete=true);
00452 
00453     /**
00454      * Writes this functor to the given handler.
00455      */
00456     virtual bool write(ioHandler &handler, const bool complete=true) const;
00457 
00458   protected:
00459     /**
00460      * compute the outer product of two vector<T> and leave the result
00461      * in a matrix<sqrType>
00462      */
00463     void outer(const vector<T>& a,
00464                const vector<T>& b,
00465                matrix<sqrType>& dest) const;
00466 
00467 
00468     /**
00469      * accumulate the outer product of a and b in the matrix dest
00470      * The matrix dest MUST have the correct size before calling this method.
00471      */
00472     void outerAcc(const vector<T>& a,
00473                   const vector<T>& b,
00474                   matrix<sqrType>& dest) const;
00475 
00476     /**
00477      * accumulate n times the outer product of a and b in the matrix dest
00478      * The matrix dest MUST have the correct size before calling this method.
00479      */
00480     void outerAcc(const vector<T>& a,
00481                   const vector<T>& b,
00482                   const int n,
00483                   matrix<sqrType>& dest) const;
00484     
00485     /**
00486      * get diagonal vector of the given matrix, but casted into the lower type
00487      */
00488     void diagonal(const matrix<sqrType>& mat,vector<T>& diag) const;
00489 
00490   private:
00491     /**
00492      * sum of vectors
00493      */
00494     vector<T> sumX;   
00495 
00496     /**
00497      * sum of outer products of vectors
00498      */
00499     matrix<sqrType> sumXXT;
00500 
00501     /**
00502      * number of vector considered so far!
00503      */
00504     double nv; 
00505     
00506   };
00507 
00508   template <class T>
00509   bool read(ioHandler& handler,
00510             serialVectorStats<T>& pca,
00511             const bool complete=true) {
00512     return pca.read(handler,complete);
00513   }
00514 
00515 
00516   template <class T>
00517   bool write(ioHandler& handler,
00518              const serialVectorStats<T>& pca,
00519              const bool complete=true) {
00520     return pca.write(handler,complete);
00521   }
00522 
00523 }
00524 
00525 #include "ltiSerialVectorStats_template.h"
00526 
00527 #endif

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