latest version v1.9 - last update 10 Apr 2010 |
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