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

ltiHistogram.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 .......: 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

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