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

ltiEntropyFunctor.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 .......: ltiEntropyFunctor.h
00027  * authors ....: Stefan Syberichs
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 5.2.2001
00030  * revisions ..: $Id: ltiEntropyFunctor.h,v 1.10 2006/02/08 12:19:09 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_ENTROPY_FUNCTOR_H_
00034 #define _LTI_ENTROPY_FUNCTOR_H_
00035 
00036 #include "ltiStatisticsFunctor.h"
00037 #include "ltiVector.h"
00038 #include "ltiMatrix.h"
00039 
00040 namespace lti {
00041   /**
00042    * Functor which computes entropy for vectors and matrices.  The
00043    * template parameter T corresponds to the value type of the objects
00044    * to be evaluated.  For example, to calculate the entropy of a
00045    * vector<double> you will need an entropyFunctor<double>.
00046    *
00047    * This functor assumes that the rows (or columns) of matrix contain
00048    * probability distributions, i.e. the sum of the rows (column) elements
00049    * must be 1.0.  The entropy for the row will be defined as the sum of
00050    * p(x)*ln(p(x)) for all x, where p(x) are the elements of the vector, row
00051    * or column.
00052    */
00053   template <class T> class entropyFunctor : public statisticsFunctor {
00054   public:
00055     /**
00056      * the parameters for the class entropyFunctor
00057      */
00058     class parameters : public statisticsFunctor::parameters {
00059     public:
00060       /**
00061        * default constructor
00062        */
00063       parameters() : statisticsFunctor::parameters() {
00064         rowWise=true;
00065         normalize = false;
00066       };
00067 
00068       /**
00069        * copy constructor
00070        * @param other the parameters object to be copied
00071        */
00072       parameters(const parameters& other) : statisticsFunctor::parameters() {
00073         copy(other);
00074       };
00075 
00076       /**
00077        * destructor
00078        */
00079       ~parameters() {
00080       };
00081 
00082       /**
00083        * returns name of this type
00084        */
00085       const char* getTypeName() const {
00086         return "entropyFunctor::parameters";
00087       };
00088 
00089       /**
00090        * copy the contents of a parameters object
00091        * @param other the parameters object to be copied
00092        * @return a reference to this parameters object
00093        */
00094       parameters& copy(const parameters& other) {
00095 #     ifndef _LTI_MSC_6
00096         // MS Visual C++ 6 is not able to compile this...
00097         statisticsFunctor::parameters::copy(other);
00098 #     else
00099         // ...so we have to use this workaround.
00100         // Conditional on that, copy may not be virtual.
00101         statisticsFunctor::parameters&
00102           (statisticsFunctor::parameters::* p_copy)
00103           (const statisticsFunctor::parameters&) =
00104           statisticsFunctor::parameters::copy;
00105         (this->*p_copy)(other);
00106 #     endif
00107 
00108         rowWise=other.rowWise;
00109         normalize=other.normalize;
00110 
00111         return *this;
00112       };
00113 
00114       /**
00115        * returns a pointer to a clone of the parameters
00116        */
00117       virtual functor::parameters* clone() const {
00118         return new parameters(*this);
00119       };
00120 
00121 #     ifndef _LTI_MSC_6
00122       /**
00123        * write the parameters in the given ioHandler
00124        * @param handler the ioHandler to be used
00125        * @param complete if true (the default) the enclosing begin/end will
00126        *        be also written, otherwise only the data block will be written.
00127        * @return true if write was successful
00128        */
00129       virtual bool write(ioHandler& handler,const bool complete=true) const
00130 #     else
00131       /**
00132        * this function is required by MSVC only, as a workaround for a
00133        * very awful bug, which exists since MSVC V.4.0, and still by
00134        * V.6.0 with all bugfixes (so called "service packs") remains
00135        * there...  This method is also public due to another bug, so please
00136        * NEVER EVER call this method directly: use write() instead
00137        */
00138       bool writeMS(ioHandler& handler,const bool complete=true) const
00139 #     endif
00140       {
00141         bool b = true;
00142         if (complete) {
00143           b = handler.writeBegin();
00144         }
00145         
00146         if (b) {
00147           lti::write(handler,"rowWise",rowWise);
00148           lti::write(handler,"normalize",normalize);
00149         }
00150 
00151 #     ifndef _LTI_MSC_6
00152         // This is the standard C++ code, which MS Visual C++ 6 is not able to
00153         // compile...
00154         b = b && statisticsFunctor::parameters::write(handler,false);
00155 #     else
00156         bool (statisticsFunctor::parameters::* p_writeMS)(ioHandler&,
00157                                                           const bool) const =
00158           statisticsFunctor::parameters::writeMS;
00159         b = b && (this->*p_writeMS)(handler,false);
00160 #     endif
00161 
00162         if (complete) {
00163           b = b && handler.writeEnd();
00164         }
00165 
00166         return b;
00167       }
00168 
00169 #     ifdef _LTI_MSC_6
00170       /**
00171        * write the parameters in the given ioHandler
00172        * @param handler the ioHandler to be used
00173        * @param complete if true (the default) the enclosing begin/end will
00174        *        be also written, otherwise only the data block will be written.
00175        * @return true if write was successful
00176        */
00177       bool write(ioHandler& handler,
00178                  const bool complete) const {
00179         // ...we need this workaround to cope with another really
00180         // awful MSVC bug.
00181         return writeMS(handler,complete);
00182       }
00183 #     endif
00184 
00185 
00186 #     ifndef _LTI_MSC_6
00187       /**
00188        * read the parameters from the given ioHandler
00189        * @param handler the ioHandler to be used
00190        * @param complete if true (the default) the enclosing begin/end will
00191        *        be also written, otherwise only the data block will be written.
00192        * @return true if write was successful
00193        */
00194       virtual bool read(ioHandler& handler,const bool complete=true)
00195 #     else
00196       /**
00197        * this function is required by MSVC only, as a workaround for a
00198        * very awful bug, which exists since MSVC V.4.0, and still by
00199        * V.6.0 with all bugfixes (so called "service packs") remains
00200        * there...  This method is also public due to another bug, so please
00201        * NEVER EVER call this method directly: use read() instead
00202        */
00203       bool readMS(ioHandler& handler,const bool complete)
00204 #     endif
00205       {
00206         bool b = true;
00207         if (complete) {
00208           b = handler.readBegin();
00209         }
00210         
00211         if (b) {
00212           lti::read(handler,"rowWise",rowWise);
00213           lti::read(handler,"normalize",normalize);
00214         }
00215 
00216 #       ifndef _LTI_MSC_6
00217         // This is the standard C++ code, which MS Visual C++ 6 is not
00218         // able to compile...
00219         b = b && statisticsFunctor::parameters::read(handler,false);
00220 #       else
00221         bool (statisticsFunctor::parameters::* p_readMS)(ioHandler&,
00222                                                          const bool) =
00223           statisticsFunctor::parameters::readMS;
00224         b = b && (this->*p_readMS)(handler,false);
00225 #       endif
00226 
00227         if (complete) {
00228           b = b && handler.readEnd();
00229         }
00230         
00231         return b;
00232       }
00233 
00234 #     ifdef _LTI_MSC_6
00235       /**
00236        * read the parameters from the given ioHandler
00237        * @param handler the ioHandler to be used
00238        * @param complete if true (the default) the enclosing begin/end will
00239        *        be also written, otherwise only the data block will be written.
00240        * @return true if write was successful
00241        */
00242       bool read(ioHandler& handler,const bool complete) {
00243         // ...we need this workaround to cope with another really awful MSVC
00244         // bug.
00245         return readMS(handler,complete);
00246       }
00247 #     endif
00248 
00249       /**
00250        * If this flag is true, the entropy computation will be row-wise, i.e.
00251        * the result will contain the entropy of the rows. This is much faster
00252        * than column-wise, since data do not have to be copied.
00253        * Default value: true
00254        */
00255       bool rowWise;
00256 
00257       /**
00258        * if false, it will be assume that the matrices or vectors are
00259        * already normalized, and can be considered directly as probability
00260        * distributions (which sum is 1.0).  If true, the vectors and matrices
00261        * will be "normalized" first, in an efficient way.
00262        * Default value: false
00263        */
00264       bool normalize;
00265     };
00266 
00267     /**
00268      * default constructor
00269      */
00270     entropyFunctor();
00271 
00272     /**
00273      * constructor with parameter preinitialization
00274      */
00275     entropyFunctor(const bool& normalize,const bool& rowWise=true);
00276 
00277     /**
00278      * copy constructor
00279      * @param other the object to be copied
00280      */
00281     entropyFunctor(const entropyFunctor& other);
00282 
00283     /**
00284      * destructor
00285      */
00286     virtual ~entropyFunctor();
00287 
00288     /**
00289      * returns the name of this type ("entropyFunctor")
00290      */
00291     virtual const char* getTypeName() const;
00292 
00293     /**
00294      * returns the entropy of the current vector.
00295      *
00296      * The entropy is defined as the sum for all vector elements of
00297      * p(x)*ln(p(x)), with p(x) = srcdest.at(x). Warning: Elements that 
00298      * are less than zero are ignored.
00299      * @param srcdest vector<T> with the source data.  The result
00300      *                 will be left here too.
00301      * @result a reference to the <code>srcdest</code>.
00302      */
00303     T apply(const vector<T>& srcdest) const;
00304 
00305     /**
00306      * computes the entropy of the given vector.
00307      *
00308      * The entropy is defined as the sum for all vector elements of
00309      * p(x)*ln(p(x)), with p(x) = srcdest.at(x). Warning: Elements that 
00310      * are less than zero are ignored.
00311      *
00312      * @param src vector<T> with the source data.
00313      * @param dest vector<T> where the result will be left.
00314      * @result a reference to the <code>dest</code>.
00315      */
00316     T &apply(const vector<T>& src, T& dest) const;
00317 
00318     /**
00319      * The result of this function depends on the value of
00320      * parameters.rowWise. If this parameter is true, the functor
00321      * will compute a vector, whose elements contain each the entropy
00322      * of one column of the matrix (this computes the entropy of the rows,
00323      * where each row is a data point in n-dimensional space.
00324      * if rowWise is false, the result vector contains the entropy
00325      * of the columns of the matrix (each column a data point).
00326      *
00327      * The entropy of a row or column is defined as the sum for all
00328      * its elements of p(x)*log2(p(x)), with p(x) = elements of the row or
00329      * column.
00330      *
00331      * @param src matrix<T> with the source data.
00332      * @param dest matrix<T> where the result will be left.
00333      * @result a reference to the <code>dest</code>.
00334      */
00335     vector<T>& apply(const matrix<T>& src, vector<T>& dest) const;
00336 
00337     /**
00338      * computes the entropy of the given matrix.  Consider the matrix
00339      * as a two-dimensional probability distribution.
00340      *
00341      * The entropy is defined as the sum for all vector elements of
00342      * p(x,y)*ln(p(x,y)), with p(x,y) = src.at(x,y).
00343      *
00344      * @param src matrix<T> with the source data.
00345      * @param dest matrix<T> where the result will be left.
00346      * @result a reference to the <code>dest</code>.
00347      */
00348     T &apply(const matrix<T>& src, T& dest) const;
00349 
00350     /**
00351      * This function
00352      * will compute a vector, whose elements contain each the entropy
00353      * of one column of the matrix (this computes the entropy of the rows,
00354      * where each row is a data point in n-dimensional space).
00355      * @param src matrix<T> with the source data.
00356      * @param dest matrix<T> where the result will be left.
00357      */
00358     void entropyOfRows(const matrix<T>& src, vector<T>& dest) const;
00359 
00360     /**
00361      * The result vector contains the entropy
00362      * of the columns of the matrix (each column a data point).
00363      * @param src matrix<T> with the source data.
00364      * @param dest matrix<T> where the result will be left.
00365      */
00366     void entropyOfColumns(const matrix<T>& src, vector<T>& dest) const;
00367 
00368     /**
00369      * copy data of "other" functor.
00370      * @param other the functor to be copied
00371      * @return a reference to this functor object
00372      */
00373     entropyFunctor& copy(const entropyFunctor& other);
00374 
00375     /**
00376      * returns a pointer to a clone of this functor.
00377      */
00378     virtual functor* clone() const;
00379 
00380     /**
00381      * returns used parameters
00382      */
00383     const parameters& getParameters() const;
00384   };
00385 }
00386 
00387 #endif

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