latest version v1.9 - last update 10 Apr 2010 |
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 .......: ltiHistogram.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 29.06.00 00030 * revisions ..: $Id: ltiHistogram.h,v 1.9 2006/02/08 12:26:46 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_HISTOGRAM_H_ 00034 #define _LTI_HISTOGRAM_H_ 00035 00036 #include "ltiVector.h" 00037 #include "ltiMatrix.h" 00038 00039 namespace lti { 00040 /** 00041 * Histogram template class. 00042 * 00043 * The lti::thistogram template class allows the generation of 00044 * histogram statistics for points in a n-dimensional space. 00045 * 00046 * The elements of the histogram will be indexed in each dimension \e i 00047 * between 0 an \f$n_i-1\f$. 00048 * 00049 * The class histogram is a typedef of thistogram<double> 00050 * 00051 * The use of this class for the one and two dimensional histograms 00052 * is not very efficient. You can use the inherited classes 00053 * lti::histogram1D and lti::histogram2D instead. 00054 * 00055 * The mapping of the analysed m-dimensional space to the 00056 * n-dimensional index space will be done by mapping functors. 00057 * The most usual ones are declared as internal types of 00058 * the class lti::histogram. @see lti::linearMapperFunctor, 00059 * lti::linearSatMapperFunctor 00060 * 00061 * 00062 * Example: 00063 * \code 00064 * lti::thistogram<float> hist(3,10) // creates a 3D-histogram with 10 00065 * // cells pro dimension. The total 00066 * // number of cells is 10^3=1000 00067 * \endcode 00068 * 00069 * To read the content of a histogram cell use the access operator 00070 * at(). 00071 * You can increment the value of a cell with the member put(). 00072 * 00073 * @ingroup gAggregate 00074 */ 00075 template<class T> 00076 class thistogram : public mathObject { 00077 public: 00078 00079 /** 00080 * Variable with a negative value to indicate outer bounds access! 00081 */ 00082 static inline const T& outerBoundsCell(); 00083 00084 typedef T value_type; 00085 00086 /** 00087 * The iterator is equivalent to a lti::vector<T>::iterator 00088 */ 00089 typedef typename vector<T>::iterator iterator; 00090 00091 /** 00092 * The const_iterator is equivalent to a lti::vector<T>::const_iterator 00093 */ 00094 typedef typename vector<T>::const_iterator const_iterator; 00095 00096 /** 00097 * default constructor creates an empty histogram; 00098 */ 00099 thistogram(); 00100 00101 /** 00102 * create a histogram of the given dimensionality. 00103 * 00104 * Each dimension will have the given number of cells, i.e. the histogram 00105 * will have \f$cells^{dimensions}\f$ cells. 00106 * 00107 * @param dimensions the dimensionality of the histogram. 00108 * @param cells the number of cells per dimension. 00109 */ 00110 thistogram(const int& dimensions,const int& cells); 00111 00112 /** 00113 * create a histogram with the given dimensionality. 00114 * 00115 * Each dimension \e i will have the number of cells indicated in 00116 * the \e i-th element of the vector <code>cells</code>. 00117 * 00118 * If the dimensionaly differs from the size of the given vector, the 00119 * number of cells of the dimension \e i will be given by 00120 * \f$dim_i = cells[i \, mod \, cells.size()]\f$. 00121 * 00122 * This means, if you want a 6-dimensional histogram, and your cells-vector 00123 * has only three elements [10,15,5], the number of cells per dimension 00124 * will be [10,15,5,10,15,5] 00125 * 00126 * @param dimensions the dimensionality of the histogram 00127 * @param cells a vector with the number of cell per dimension 00128 */ 00129 thistogram(const int& dimensions,const ivector& cells); 00130 00131 /** 00132 * create this histogram as a copy of another histogram 00133 * @param other the histogram to be copied. 00134 */ 00135 thistogram(const thistogram<T>& other); 00136 00137 /** 00138 * destructor 00139 */ 00140 virtual ~thistogram(); 00141 00142 /** 00143 * returns the name of this class: "histogram" 00144 */ 00145 const char* getTypeName() const {return "histogram";}; 00146 00147 /** 00148 * returns the number of dimensions of this histogram 00149 */ 00150 inline int dimensions() const; 00151 00152 /** 00153 * get the number of cells of the dimension <code>dim</code> 00154 * @param dimension the index of the dimension to be checked 00155 * @return the number of cells of the dimension specified by 00156 * <code>dim</code> 00157 */ 00158 inline int cellsInDimension(const int& dimension) const; 00159 00160 /** 00161 * get the number of cells per dimension 00162 */ 00163 inline const ivector& cellsPerDimension() const; 00164 00165 /** 00166 * returns a vector to the first element of the histogram 00167 * (usually every element of the vector is 0; 00168 */ 00169 inline const ivector& getFirstCell() const; 00170 00171 /** 00172 * returns a vector to the last element of the histogram 00173 */ 00174 inline const ivector& getLastCell() const; 00175 00176 /** 00177 * returns an iterator pointing to the first element. 00178 * Note that you can not change the values of the histogram 00179 * elements when you use a const_iterator. See also begin() 00180 */ 00181 inline const_iterator begin() const { 00182 return theHistogram.begin(); 00183 }; 00184 00185 /** 00186 * returns an iterator pointing to the first element. 00187 * The use of the interators is similar to the iterators of the 00188 * Standard Template Library (STL). 00189 * 00190 * If you need to iterate on all elements of the histogram, you can 00191 * use following code: 00192 * \code 00193 * int tmp,accu; // a temporal variable 00194 * lti::thistogram<float> myHist(3,10); // a 3D-histogram with 10 cells/dim. (of type float) 00195 * lti::thistogram<float>::iterator it; // an iterator 00196 * 00197 * for (it=myHist.begin();it!=myHist.end();it++) { 00198 * tmp = *it; // tmp has value of element pointed 00199 * // by the iterator. 00200 * accu += tmp; 00201 * (*it) = accu; // change the value in the histogram. 00202 * } 00203 * \endcode 00204 * Please note that if you define <code>it</code> as a const_iterator, 00205 * you can not make something like <code>*it=accu</code>. 00206 */ 00207 inline iterator begin() { 00208 return theHistogram.begin(); 00209 } 00210 00211 /** 00212 * returns last index as a const iterator. 00213 * For an example see begin() 00214 */ 00215 inline const_iterator end() const { 00216 return theHistogram.end(); 00217 }; 00218 00219 /** 00220 * returns last index as an iterator 00221 * For an example see begin() 00222 */ 00223 inline iterator end() { 00224 return theHistogram.end(); 00225 }; 00226 00227 /** 00228 * change dimensionality and cell number of the histogram. All data will 00229 * be lost! 00230 * 00231 * @param dimensions the new dimensionality of the histogram 00232 * @param cells the number of cells per dimension 00233 * 00234 */ 00235 void resize(const int& dimensions, 00236 const int& cells); 00237 00238 /** 00239 * change dimensionality and cell number of the histogram. All data will 00240 * be lost! 00241 * 00242 * @param dimensions the new dimensionality of the histogram 00243 * @param cells the number of cells per dimension 00244 * 00245 */ 00246 void resize(const int& dimensions, 00247 const ivector& cells); 00248 00249 /** 00250 * equivalent to resize(0,0); 00251 */ 00252 void clear(); 00253 00254 /** 00255 * initialize all cells of the histogram with 0 (or another specified 00256 * number). 00257 */ 00258 void initialize(const T& value = T(0)); 00259 00260 /** 00261 * returns the number of entries registered by now. 00262 */ 00263 inline const T& getNumberOfEntries() const; 00264 00265 /** 00266 * Normalize the histogram and then denormalize it with the given number 00267 * of entries. 00268 * 00269 * You should not use this for thistogram<int>, since rounding 00270 * errors are likely to occur. 00271 */ 00272 void setNumberOfEntries(const T& newNumberOfEntries); 00273 00274 /** 00275 * counts the number of entries in the whole histogram and sets 00276 * the internal counter for the total number of entries. 00277 * if some direct access to the cell contents 00278 * have been done, you should update the number of entries with this 00279 * function 00280 */ 00281 void updateNumberOfEntries(); 00282 00283 /** 00284 * fills the histogram elements with <code>iniValue</code> between 00285 * the n-dimensional points <code>from</code> and <code>to</code>. 00286 * @param iniValue the elements will be initialized with this 00287 * value. 00288 * @param from first element index 00289 * @param to last element index 00290 * 00291 * If <code>from</code> or <code>to</code> are out of bounds, 00292 * they will be (internaly) adjusted to a correct value. 00293 * 00294 * Example: 00295 * \code 00296 * lti::thistogram<float> hist(1,10); // 1D-histogram with 10 elements 00297 * hist.clear; 00298 * hist.fill(9.0f,ivector(1,1),ivector(1,3)); // hist=[0,9,9,9,0,0,0,0,0,0] 00299 * \endcode 00300 */ 00301 void fill(const T& iniValue, 00302 const ivector& from=ivector(), 00303 const ivector& to=ivector()); 00304 00305 /** 00306 * read-only access to the element x of the histogram 00307 * @param x index of the histogram element to be accessed. It should 00308 * be between getFirstCell() and getLastCell() 00309 * @return the number of entries in the given cell 00310 */ 00311 const T& at(const ivector& x) const; 00312 00313 /** 00314 * access element x of the histogram 00315 * @param x index of the histogram element to be accessed. It should 00316 * be between getFirstCell() and getLastCell() 00317 * @return the number of entries in the given cell 00318 */ 00319 T& at(const ivector& x); 00320 00321 /** 00322 * increment the cell at \e x by the given number of elements (or 1.0 if 00323 * nothing is explicitly indicated!) and update the number of entries in 00324 * the histogram. 00325 * @param x index of the histogram element to be incremented 00326 * @param increment amount of the incrementation (default: 1) 00327 * @return the new number of entries of the incremented cell, or 0 00328 * if the index lies outer bounds 00329 */ 00330 const T& put(const ivector& x,const T& increment=T(1)); 00331 00332 /** 00333 * read-only access to the element x of the histogram as a discrete 00334 * probability distribution term. This is equivalent to \f$at(x)/n\f$, 00335 * where \e n is the number of entries in the histogram (see 00336 * getNumberOfEntries()). 00337 * 00338 * @param x index of the histogram element to be accessed. It should 00339 * be between getFirstCell() and getLastCell() 00340 * @return the probability of the element x, respect to the histogram 00341 * data, or 0 if <code>x</code> lies outer bounds. 00342 */ 00343 double getProbability(const ivector& x) const; 00344 00345 /** 00346 * @name Copy and Duplication methods 00347 */ 00348 //@{ 00349 00350 /** 00351 * assigment operator. 00352 * copy the contents of <code>other</code> in this %object. 00353 * @param other the source histogram to be copied. 00354 * @return a reference to this object 00355 */ 00356 thistogram<T>& copy(const thistogram<T>& other); 00357 00358 /** 00359 * assigment operator (alias for copy(other)). 00360 * @param other the histogram to be copied 00361 * @return a reference to the actual histogram 00362 */ 00363 inline thistogram<T>& operator=(const thistogram<T>& other) { 00364 return copy(other); 00365 }; 00366 00367 /** 00368 * copy the <code>other</code> histogram by casting each of its elements 00369 * @param other The histogram to be casted 00370 */ 00371 template<class U> 00372 thistogram<T>& castFrom(const thistogram<U>& other) { 00373 resize(other.dimensions(), other.cellsPerDimension()); 00374 00375 typename thistogram<U>::const_iterator otherIt = other.begin(); 00376 iterator thisIt = begin(); 00377 00378 while (! (otherIt == other.end())) { 00379 *thisIt = static_cast<T>(*otherIt); 00380 otherIt++; 00381 thisIt++; 00382 } 00383 00384 updateNumberOfEntries(); 00385 00386 return (*this); 00387 }; 00388 00389 /** 00390 * create a clone of this histogram 00391 * @return a pointer to a copy of this histogram 00392 */ 00393 virtual mathObject* clone() const; 00394 00395 /** 00396 * Free the data of this object and attach it to the "receiver". 00397 * 00398 * It is a very efficient way to make a copy of this histogram, if you 00399 * don't need the source data anymore! 00400 * 00401 * At the end of the detachment, this histogram will be empty. 00402 * @param receiver the histogram which will receive the memory. 00403 * this histogram! 00404 */ 00405 void detach(thistogram<T>& receiver); 00406 //@} 00407 00408 /** 00409 * @name Comparison methods 00410 */ 00411 //@{ 00412 00413 /** 00414 * compare this histogram with another one. 00415 * 00416 * @param other the other histogram to be compared with 00417 * @return true if both histograms have the same elements and same size 00418 */ 00419 bool equals(const thistogram<T>& other) const; 00420 00421 /** compare this histogram with other 00422 * 00423 * @param other the other histogram to be compared with 00424 * @return true if both histograms have the same elements and same size 00425 */ 00426 inline bool operator==(const thistogram<T>& other) const { 00427 return equals(other); 00428 }; 00429 00430 /** 00431 * compare this histogram with another one, and use the given tolerance to 00432 * determine if the value of each element of the other histogram 00433 * approximately equals the values of the actual histogram elements. 00434 * 00435 * An element \e x is approximately equal to another element \e y 00436 * with a tolerance \e t, if following equation holds: 00437 * <i>x</i>-t < <i>y</i> < <i>x</i>+t 00438 * 00439 * @param other the other histogram to be compared with 00440 * @param tolerance the tolerance to be used 00441 * 00442 * @return true if both histograms are approximatly equal 00443 */ 00444 bool prettyCloseTo(const thistogram<T>& other, 00445 const T& tolerance) const; 00446 00447 00448 //@} 00449 00450 /** 00451 * Apply methods 00452 */ 00453 //@{ 00454 /** 00455 * applies a C-function to each element of the histogram. 00456 * @param function a pointer to a C-function 00457 * @return a reference to the actual histogram 00458 */ 00459 thistogram<T>& apply(T (*function)(T)); 00460 00461 /** 00462 * applies a C-function to each element of the histogram. 00463 * @param function a pointer to a C-function 00464 * @return a reference to the actual histogram 00465 */ 00466 thistogram<T>& apply(T (*function)(const T&)); 00467 //@} 00468 00469 /** 00470 * @name Arithmetical operations 00471 */ 00472 //@{ 00473 00474 /** 00475 * Elementwise multiplication. 00476 * Each element of this histogram will be multiplied with the elements 00477 * of the other histogram and the result will be left in this %object! 00478 * 00479 * Both histograms are first normalized, then multiplied, and the number of 00480 * entries is after the multiplication 1! After this multiplication, this 00481 * histogram cannot be anymore interpreted as a histogram, but as a 00482 * combined probabilty distribution. You can use setNumberOfEntries() to 00483 * change this fact under your own risk (the semathical meaning of that is 00484 * left to you!). 00485 * 00486 * You should not use this with thistogram<int>. 00487 * 00488 * The returned histogram is this %object! 00489 * 00490 * @param other the other histogram to be multiplied with 00491 * @return a reference to the actual histogram 00492 */ 00493 thistogram<T>& emultiply(const thistogram<T>& other); 00494 00495 /** 00496 * Elementwise multiplication. 00497 * This histogram will contain the elementwise multiplication of the 00498 * elements in <code>first</code> and <code>second</code>. 00499 * 00500 * Both histograms are first normalized, then multiplied, and the number of 00501 * entries is after the multiplication 1! After this multiplication, this 00502 * histogram cannot be anymore interpreted as a histogram, but as a 00503 * combined probabilty distribution. You can use setNumberOfEntries() to 00504 * change this fact under your own risk (the semathical meaning of that is 00505 * left to you!). 00506 * 00507 * You should not use this with thistogram<int>. 00508 * 00509 * @param first the first histogram 00510 * @param second the second histogram will be multiplied with the 00511 * first histogram 00512 * @return a reference to the actual histogram 00513 */ 00514 thistogram<T>& emultiply(const thistogram<T>& first, 00515 const thistogram<T>& second); 00516 00517 /** 00518 * Add another histogram of the same type and same dimension and 00519 * leave the result in this %object. The number of entries of both 00520 * histograms are also added. 00521 * 00522 * @param other the other histogram to be added with 00523 * @return a reference to the actual histogram 00524 */ 00525 thistogram<T>& add(const thistogram<T>& other); 00526 00527 /** 00528 * Add two histogram and leave the result in this %object. 00529 * @param first the first histogram. The number of entries of both 00530 * histograms are also added. 00531 * @param second the second histogram will be added with the first 00532 * histogram 00533 * @return a reference to the actual histogram 00534 */ 00535 thistogram<T>& add(const thistogram<T>& first,const thistogram<T>& second); 00536 00537 /// Alias for add(const histogram& other) 00538 inline thistogram<T>& operator+=(const thistogram<T>& other) { 00539 return add(other); 00540 }; 00541 00542 /** 00543 * Subtracts another histogram of the same type and same dimension 00544 * and leaves the result in this %object 00545 * 00546 * @param other will be substracted from this histogram 00547 * @return a reference to the actual histogram 00548 */ 00549 thistogram<T>& subtract(const thistogram<T>& other); 00550 00551 /** 00552 * Subtracts two histograms and leaves the result in this %object. 00553 * @param first the first histogram 00554 * @param second the second histogram will be substracted from the 00555 * first histogram 00556 * @return a reference to the actual histogram 00557 */ 00558 thistogram<T>& subtract(const thistogram<T>& first, 00559 const thistogram<T>& second); 00560 00561 /** 00562 * Alias for substract(const histogram& other) 00563 */ 00564 inline thistogram<T>& operator-=(const thistogram<T>& other) { 00565 return subtract(other); 00566 }; 00567 00568 /** 00569 * Multiply this histogram with a constant. 00570 * Returns this histogram. The total number of entries will also be 00571 * updated. Note that if you use this operation, the number of entries 00572 * could be false at the end due to numerical instabilities. 00573 * @see setNumberOfEntries() 00574 * 00575 * @param cst constant scalar to be multiplied with 00576 * @return a reference to the actual histogram 00577 */ 00578 thistogram<T>& multiply(const T& cst); 00579 00580 /** 00581 * Multiply the other %histogram with a constant and leave the result here. 00582 * Returns a reference to this histogram. 00583 * Note that if you use this operation, the number of entries 00584 * could be false at the end due to numerical instabilities. 00585 * @see setNumberOfEntries() 00586 * 00587 * @param other the other histogram to be multiplied with the 00588 * constant value 00589 * @param cst constant scalar to be multiplied with the other histogram. 00590 * @return a reference to the actual histogram 00591 */ 00592 thistogram<T>& multiply(const thistogram<T>& other,const T& cst); 00593 00594 /** 00595 * alias for multiply(const T& cst) 00596 * @param cst constant scalar to be multiplied with 00597 * @return a reference to the actual histogram 00598 */ 00599 inline thistogram<T>& operator*=(const T& cst) { 00600 return multiply(cst); 00601 }; 00602 00603 /** 00604 * Divide this histogram with a constant. 00605 * 00606 * Returns this histogram. 00607 * 00608 * Keep in mind, that rounding errors might occur if you use this 00609 * with thistogram<int>. 00610 * 00611 * @param cst the elements of the histogram will be divided with this 00612 * constant 00613 * @return a reference to the actual histogram 00614 */ 00615 thistogram<T>& divide(const T& cst); 00616 00617 /** 00618 * Divide the other histogram with a constant and leave the result here. 00619 * 00620 * Returns a reference to this histogram. 00621 * 00622 * Keep in mind, that rounding errors might occur if you use this 00623 * with thistogram<int>. 00624 * 00625 * @param other the histogram to be divide by the constant value 00626 * @param cst the elements of the histogram will be divided with this 00627 * constant 00628 * @return a reference to the actual histogram 00629 */ 00630 thistogram<T>& divide(const thistogram<T>& other,const T& cst); 00631 00632 /** 00633 * Add constant to this histogram. This histogram is changed. 00634 * Returns this histogram. 00635 * @param cst constant scala to be added with each element 00636 * @return a reference to the actual histogram 00637 */ 00638 thistogram<T>& add(const T& cst); 00639 00640 /** 00641 * Alias for add(const T& cst) 00642 */ 00643 thistogram<T>& operator+=(const T& cst) { 00644 return add(cst); 00645 } 00646 00647 /** 00648 * Add constant to the other histogram and leave the result here. 00649 * Returns a reference to this histogram. 00650 * @param other the oder histogram 00651 * @param cst constant scala to be added with each element of the other 00652 * histogram 00653 * @return a reference to the actual histogram 00654 */ 00655 thistogram<T>& add(const thistogram<T>& other,const T& cst); 00656 00657 /** 00658 * Normalize the histogram 00659 * 00660 * The default behaviour just divides the content of each bin by the 00661 * current number of entries. Since some operations (especially if you 00662 * use apply()) can "corrupt" the consistence of this internal attribute, 00663 * you can additionally specify with the boolean parameter, that you want 00664 * to force the recomputation the number of entries. 00665 * 00666 * The total number of entries will be set to 1.0 00667 * You should not use this with thistogram<int>. 00668 * 00669 * @param forceUpdateOfNumEntries if true, the number of entries will be 00670 * recomputed, ignoring their previous 00671 * content. If false (default), the current 00672 * value will be used. 00673 * 00674 * @return a reference to the actual histogram 00675 */ 00676 thistogram<T>& normalize(const bool forceUpdateOfNumEntries=false); 00677 00678 //@} 00679 00680 /** 00681 * @name Search for extrema 00682 */ 00683 //@{ 00684 /** 00685 * search for the maximum entry in the histogram and return its value 00686 */ 00687 inline T maximum() const { 00688 return theHistogram.maximum(); 00689 } 00690 00691 /** 00692 * get the index of the biggest element in the histogram 00693 */ 00694 inline ivector getIndexOfMaximum() const; 00695 00696 /** 00697 * search for the minimum entry in the histogram and return its value 00698 */ 00699 inline T minimum() const { 00700 return theHistogram.minimum(); 00701 } 00702 00703 /** 00704 * get the index of the biggest element in the histogram 00705 */ 00706 inline ivector getIndexOfMinimum() const; 00707 00708 //@} 00709 00710 /** 00711 * @name Serialization interface 00712 */ 00713 //@{ 00714 /** 00715 * write the object in the given ioHandler 00716 */ 00717 virtual bool write(ioHandler& handler,const bool complete = true) const; 00718 00719 /** 00720 * read the object from the given ioHandler 00721 */ 00722 virtual bool read(ioHandler& handler,const bool complete = true); 00723 //@} 00724 00725 protected: 00726 /** 00727 * the total number of cells 00728 */ 00729 int totalNumberOfCells; 00730 00731 /** 00732 * the registered number of entries 00733 */ 00734 T numberOfEntries; 00735 00736 /** 00737 * the dimensionality of this histogram 00738 */ 00739 int dimensionality; 00740 00741 /** 00742 * the data of the histogram 00743 */ 00744 vector<T> theHistogram; 00745 00746 /** 00747 * number of cells 00748 */ 00749 ivector theCellsPerDimension; 00750 00751 /** 00752 * a vector with the right dimension initialized with 0 00753 */ 00754 ivector firstCell; 00755 00756 /** 00757 * a vector with the right dimension initialized with the 00758 * number of cells - 1 per dimension 00759 */ 00760 ivector lastCell; 00761 00762 /** 00763 * compute the integer index for the data vector using the 00764 * given index vector. 00765 */ 00766 inline int vectorToIndex(const ivector& x) const; 00767 00768 /* 00769 * compute the index vector for the data vector using the 00770 * given integer index. 00771 */ 00772 inline ivector indexToVector(const int x) const; 00773 }; 00774 00775 /** 00776 * read the matrix from the given ioHandler. The complete flag indicates 00777 * if the enclosing begin and end should be also be read 00778 * 00779 * @ingroup gStorable 00780 */ 00781 template <class T> 00782 bool read(ioHandler& handler,thistogram<T>& hist,const bool complete=true) { 00783 return hist.read(handler,complete); 00784 } // immediate implementation to avoid MSVC++ bug!! 00785 00786 /** 00787 * write the matrix in the given ioHandler. The complete flag indicates 00788 * if the enclosing begin and end should be also be written or not 00789 * 00790 * @ingroup gStorable 00791 */ 00792 template <class T> 00793 bool write(ioHandler& handler,const thistogram<T>& hist, 00794 const bool complete=true) { 00795 return hist.write(handler,complete); 00796 } // immediate implementation to avoid MSVC++ bug!! 00797 00798 00799 // -------------------------------------------------------------------- 00800 00801 typedef thistogram<double> histogram; 00802 00803 // -------------------------------------------------------------------- 00804 00805 00806 /** 00807 * one dimensional histogram of type double 00808 * 00809 * The implementation of the 1D histogram allows an efficient way 00810 * to create 1D histogram... much faster than using n-dimensional 00811 * histograms with dimension 1. 00812 * 00813 * @ingroup gAggregate 00814 */ 00815 class histogram1D : public histogram { 00816 public: 00817 00818 /** 00819 * default constructor creates an empty histogram; 00820 */ 00821 histogram1D(); 00822 00823 /** 00824 * create a one dimensional histogram of the given dimensionality. 00825 * 00826 * @param cells the number of cells. 00827 */ 00828 histogram1D(const int& cells); 00829 00830 /** 00831 * create this histogram as a copy of another histogram 00832 * @param other the histogram to be copied. 00833 */ 00834 histogram1D(const histogram1D& other); 00835 00836 /** 00837 * destructor 00838 */ 00839 virtual ~histogram1D(); 00840 00841 /** 00842 * returns the name of this class: "histogram" 00843 */ 00844 const char* getTypeName() const {return "histogram1D";}; 00845 00846 /** 00847 * Returns the index of the first histogram element, which is always zero 00848 */ 00849 inline const int& getFirstCell() const; 00850 00851 /** 00852 * Returns a vector to the last element of the histogram 00853 */ 00854 inline const int& getLastCell() const; 00855 00856 /** 00857 * Returns the total number of cells in this histogram 00858 * 00859 * This method is slower than getLastCell, since it need to make some 00860 * arithmetical operations. You should use getLastCell instead. 00861 */ 00862 inline int size() const; 00863 00864 /** 00865 * change cell number of the histogram. All data will 00866 * be lost! (it will be initialized with 0) 00867 * 00868 * @param cells the number of cells per dimension 00869 * 00870 */ 00871 void resize(const int& cells); 00872 00873 /** 00874 * initialize all cells of the histogram with 0 (or another specified 00875 * number). 00876 */ 00877 void initialize(const value_type& value = value_type(0)); 00878 00879 /** 00880 * fills the histogram elements with <code>iniValue</code> between 00881 * the n-dimensional points <code>from</code> and <code>to</code>. 00882 * @param iniValue the elements will be initialized with this 00883 * value. 00884 * @param from first element index 00885 * @param to last element index 00886 * 00887 * If <code>from</code> or <code>to</code> are out of bounds, 00888 * they will be (internaly) adjusted to a correct value. 00889 * 00890 * Example: 00891 * \code 00892 * lti::histogram1D hist(10); // 1D-histogram with 10 elements 00893 * hist.clear(); 00894 * hist.fill(9,1,3); // hist=[0,9,9,9,0,0,0,0,0,0] 00895 * \endcode 00896 */ 00897 void fill(const value_type& iniValue, 00898 const int& from=0, 00899 const int& to=MaxInt32); 00900 00901 /** 00902 * read-only access to the element x of the histogram 00903 * @param x index of the histogram element to be accessed. It should 00904 * be between getFirstCell() and getLastCell() 00905 * @return the number of entries in the given cell 00906 */ 00907 inline const value_type& at(const int& x) const; 00908 00909 /** 00910 * access element x of the histogram 00911 * @param x index of the histogram element to be accessed. It should 00912 * be between getFirstCell() and getLastCell() 00913 * @return the number of entries in the given cell 00914 */ 00915 inline value_type& at(const int& x); 00916 00917 /** 00918 * increment the cell at \e x by the given number of elements (or 1.0 if 00919 * nothing is explicitly indicated!) and update the number of entries in 00920 * the histogram. 00921 * @param x index of the histogram element to be incremented 00922 * @param increment amount of the incrementation (default: 1) 00923 * @return the new number of entries of the incremented cell. 00924 */ 00925 inline const value_type& put(const int& x, 00926 const value_type& increment=1.0f); 00927 00928 /** 00929 * read-only access to the element x of the histogram as a discrete 00930 * probability distribution term. This is equivalent to \f$at(x)/n\f$, 00931 * where \e n is the number of entries in the histogram (see 00932 * getNumberOfEntries()). 00933 * 00934 * @param x index of the histogram element to be accessed. It should 00935 * be between getFirstCell() and getLastCell() 00936 * @return the probabilty of the element x, respect to the histogram 00937 * data. 00938 */ 00939 inline value_type getProbability(const int& x) const; 00940 00941 /** 00942 * assigment operator. 00943 * copy the contents of <code>other</code> in this %object. 00944 * @param other the source histogram to be copied. 00945 * @return a reference to this object 00946 */ 00947 virtual histogram1D& copy(const histogram1D& other); 00948 00949 /** 00950 * create a clone of this histogram 00951 * @return a pointer to a copy of this histogram 00952 */ 00953 mathObject* clone() const; 00954 00955 00956 /** 00957 * assigment operator (alias for copy(other)). 00958 * @param other the histogram to be copied 00959 * @return a reference to the actual histogram 00960 */ 00961 histogram1D& operator=(const histogram1D& other) {return copy(other);}; 00962 00963 /** 00964 * get the index of the biggest element in the histogram 00965 */ 00966 inline int getIndexOfMaximum() const; 00967 00968 /** 00969 * get the index of the smallest element in the histogram 00970 */ 00971 inline int getIndexOfMinimum() const; 00972 00973 /** 00974 * write the object in the given ioHandler 00975 */ 00976 virtual bool write(ioHandler& handler,const bool complete = true) const; 00977 00978 /** 00979 * read the object from the given ioHandler 00980 */ 00981 virtual bool read(ioHandler& handler,const bool complete = true); 00982 00983 protected: 00984 00985 /** 00986 * first index ( 0 ) 00987 */ 00988 int firstCell; 00989 00990 /** 00991 * last index (cellsInDimension(0) - 1) 00992 */ 00993 int lastCell; 00994 00995 }; 00996 00997 // -------------------------------------------------------------------- 00998 00999 01000 /** 01001 * two dimensional histogram of type double 01002 * 01003 * The implementation of the 2D histogram allows an efficient way 01004 * to create 2D histograms... much faster than using n-dimensional 01005 * histograms with dimension 2. 01006 * 01007 * @ingroup gAggregate 01008 */ 01009 class histogram2D : public histogram { 01010 public: 01011 /** 01012 * default constructor creates an empty histogram; 01013 */ 01014 histogram2D(); 01015 01016 /** 01017 * create a two dimensional histogram of \e cells x \e cells 01018 * 01019 * @param cells the number of cells per dimension. 01020 */ 01021 histogram2D(const int& cells); 01022 01023 /** 01024 * create a two dimensional histogram of \e cellsY x \e cellsX 01025 * 01026 * Please note the use of matrix notation (y,x) and NOT (x,y) 01027 * @param cellsY the number of cells in the first dimension. 01028 * @param cellsX the number of cells in the second dimension. 01029 */ 01030 histogram2D(const int& cellsY,const int& cellsX); 01031 01032 /** 01033 * create a two dimensional histogram of \e cells.x x \e cells.y 01034 * 01035 * @param cells the number of cells per dimension. 01036 * (cells.x is the number of columns of the histogram 01037 * cells.y is the number of rows of the histogram) 01038 */ 01039 histogram2D(const point& cells); 01040 01041 /** 01042 * create this histogram as a copy of another histogram 01043 * @param other the histogram to be copied. 01044 */ 01045 histogram2D(const histogram2D& other); 01046 01047 /** 01048 * destructor 01049 */ 01050 virtual ~histogram2D(); 01051 01052 /** 01053 * returns the name of this class: "histogram" 01054 */ 01055 const char* getTypeName() const {return "histogram2D";}; 01056 01057 /** 01058 * returns a vector to the first element of the histogram 01059 * (usually every element of the vector is 0; 01060 */ 01061 inline const point& getFirstCell() const; 01062 01063 /** 01064 * returns a vector to the last element of the histogram 01065 */ 01066 inline const point& getLastCell() const; 01067 01068 /** 01069 * change cell number of the histogram2D. All data will 01070 * be lost! 01071 * 01072 * @param cells the number of cells 01073 * 01074 */ 01075 void resize(const point& cells); 01076 01077 /** 01078 * change cell number of the histogram. All data will 01079 * be lost! 01080 * 01081 * @param cellsY the number of rows 01082 * @param cellsX the number of columns 01083 * 01084 */ 01085 void resize(const int& cellsY,const int& cellsX); 01086 01087 /** 01088 * initialize all cells of the histogram with 0 (or another specified 01089 * number). 01090 */ 01091 void initialize(const value_type& value = value_type(0)); 01092 01093 /** 01094 * fills the histogram elements with <code>iniValue</code> between 01095 * the n-dimensional points <code>from</code> and <code>to</code>. 01096 * @param iniValue the elements will be initialized with this 01097 * value. 01098 * @param from first element index 01099 * @param to last element index 01100 * 01101 * If <code>from</code> or <code>to</code> are out of bounds, 01102 * they will be (internaly) adjusted to a correct value. 01103 * 01104 * Example: 01105 * \code 01106 * lti::histogram1D hist(10); // 1D-histogram with 10 elements 01107 * hist.clear(); 01108 * hist.fill(9,1,3); // hist=[0,9,9,9,0,0,0,0,0,0] 01109 * \endcode 01110 */ 01111 void fill(const value_type& iniValue, 01112 const point& from=point(0,0), 01113 const point& to=point(MaxInt32,MaxInt32)); 01114 01115 /** 01116 * read-only access to the element (x,y) of the histogram 01117 * 01118 * Note the use of the matrix notation: first row (y) and then column (x) 01119 * @param y row of the histogram element to be accessed. It should 01120 * be between getFirstCell().y and getLastCell().y 01121 * @param x column of the histogram element to be accessed. It should 01122 * be between getFirstCell().x and getLastCell().x 01123 * @return the number of entries in the given cell 01124 */ 01125 inline const value_type& at(const int& y, const int& x) const; 01126 01127 /** 01128 * access element x of the histogram 01129 * @param y row of the histogram element to be accessed. It should 01130 * be between getFirstCell().y and getLastCell().y 01131 * @param x column of the histogram element to be accessed. It should 01132 * be between getFirstCell().x and getLastCell().x 01133 * @return the number of entries in the given cell 01134 */ 01135 inline value_type& at(const int& y, const int& x); 01136 01137 /** 01138 * read-only access to the element p of the histogram 01139 * @param p index of the histogram element to be accessed. It should 01140 * be between getFirstCell() and getLastCell() 01141 * @return the number of entries in the given cell 01142 */ 01143 inline const value_type& at(const point& p) const; 01144 01145 /** 01146 * access element p of the histogram 01147 * @param p index of the histogram element to be accessed. It should 01148 * be between getFirstCell() and getLastCell() 01149 * @return the number of entries in the given cell 01150 */ 01151 inline value_type& at(const point& p); 01152 01153 /** 01154 * increment the cell at row \e y and column \e x by the given number of 01155 * entries (or 1.0 if nothing is explicitly indicated!) and update the 01156 * total number of entries in the histogram. 01157 * @param y row of the histogram element to be incremented. It should 01158 * be between getFirstCell().y and getLastCell().y 01159 * @param x column of the histogram element to be incremented. It should 01160 * be between getFirstCell().x and getLastCell().x 01161 * @param increment amount of the incrementation (default: 1) 01162 * @return the new number of entries of the incremented cell. 01163 */ 01164 inline const value_type& put(const int& y,const int& x, 01165 const value_type& increment=value_type(1)); 01166 01167 /** 01168 * increment the cell at p by the given number of 01169 * entries (or 1.0 if nothing is explicitly indicated!) and update the 01170 * total number of entries in the histogram. 01171 * @param p index of the histogram element to be incremented. It should 01172 * be between getFirstCell() and getLastCell() 01173 * @param increment amount of the incrementation (default: 1) 01174 * @return the new number of entries of the incremented cell. 01175 */ 01176 inline const value_type& put(const point& p, 01177 const value_type& increment=value_type(1)); 01178 01179 01180 /** 01181 * read-only access to the element p of the histogram as a discrete 01182 * probability distribution term. This is equivalent to \f$at(x)/n\f$, 01183 * where \e n is the number of entries in the histogram (see 01184 * getNumberOfEntries()). 01185 * 01186 * @param p index of the histogram element to be accessed. It should 01187 * be between getFirstCell() and getLastCell() 01188 * @return the probabilty of the element x, respect to the histogram 01189 * data. 01190 */ 01191 inline value_type getProbability(const point& p) const; 01192 01193 01194 /** 01195 * read-only access to the element of the row y and the column x of the 01196 * histogram as a discrete probability distribution term. This is 01197 * equivalent to \f$at(x)/n\f$, where \e n is the number of entries in the 01198 * histogram (see getNumberOfEntries()). 01199 * 01200 * @param y row of the histogram element to be accessed. It should 01201 * be between getFirstCell().y and getLastCell().y 01202 * @param x column of the histogram element to be accessed. It should 01203 * be between getFirstCell().x and getLastCell().x 01204 * @return the probabilty of the element (y,x), respect to the histogram 01205 * data. 01206 */ 01207 inline value_type getProbability(const int& y, const int& x) const; 01208 01209 /** 01210 * assigment operator. 01211 * copy the contents of <code>other</code> in this %object. 01212 * @param other the source histogram to be copied. 01213 * @return a reference to this object 01214 */ 01215 virtual histogram2D& copy(const histogram2D& other); 01216 01217 /** 01218 * create a clone of this histogram 01219 * @return a pointer to a copy of this histogram 01220 */ 01221 mathObject* clone() const; 01222 01223 /** 01224 * assigment operator (alias for copy(other)). 01225 * @param other the histogram to be copied 01226 * @return a reference to the actual histogram 01227 */ 01228 histogram2D& operator=(const histogram2D& other) {return copy(other);}; 01229 01230 /** 01231 * get the index of the biggest element in the histogram 01232 */ 01233 inline point getIndexOfMaximum() const; 01234 01235 /** 01236 * get the index of the smallest element in the histogram 01237 */ 01238 inline point getIndexOfMinimum() const; 01239 01240 /** 01241 * write the object in the given ioHandler 01242 */ 01243 virtual bool write(ioHandler& handler,const bool complete = true) const; 01244 01245 /** 01246 * read the object from the given ioHandler 01247 */ 01248 virtual bool read(ioHandler& handler,const bool complete = true); 01249 01250 01251 protected: 01252 01253 /** 01254 * first index ( 0,0 ) 01255 */ 01256 point firstCell; 01257 01258 /** 01259 * last index (cellsInDimension(0) - 1,cellsInDimension(1) - 1 ) 01260 */ 01261 point lastCell; 01262 01263 /** 01264 * wrapper matrix for histogram::theHistogram 01265 */ 01266 matrix<value_type> theHistoMatrix; 01267 }; 01268 01269 } // namespace lti 01270 01271 01272 /// outputs the elements of the histogram on a stream 01273 template <class T> 01274 std::ostream& operator<<(std::ostream& s,const lti::thistogram<T>& v); 01275 01276 #include "ltiHistogram_inline.h" 01277 01278 01279 #endif