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

ltiQuickMedian.h

00001 /*
00002  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 
00024 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiQuickMedian.h
00027  * authors ....: Guy Wafo
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 27.3.2001
00030  * revisions ..: $Id: ltiQuickMedian.h,v 1.7 2006/02/08 12:40:45 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_QUICKMEDIAN_H_
00034 #define _LTI_QUICKMEDIAN_H_
00035 
00036 #include "ltiFunctor.h"
00037 #include "ltiVector.h"
00038 #include "ltiMatrix.h"
00039 
00040 namespace lti {
00041 
00042   /**
00043    * This class is used to extract the median of the elements of a
00044    * given vector or matrix.  The median is defined as the element at
00045    * the middle position of the sorted vector.  The algorithm used is
00046    * based on the quick sort.
00047    * For vectors (or matrices) with an even number n of elements, the
00048    * median will be the element at (n/2) or (n/2)-1 depending on the
00049    * parameter settings.
00050    *
00051    * The type of the vector elements (T) must accept the operators <
00052    * and >.
00053    *
00054    * @ingroup gStats
00055    */
00056   template <class T>
00057   class quickMedian : public functor {
00058   public:
00059 
00060     /**
00061      * The parameters for the class quickMedian
00062      */
00063     class parameters : public functor::parameters {
00064     public:
00065       /**
00066        * Default constructor
00067        */
00068       parameters()
00069         : functor::parameters() {
00070           evenCase = TakeLower;
00071       };
00072 
00073       /**
00074        * copy constructor
00075        * @param other the parameters object to be copied
00076        */
00077       parameters(const parameters& other) 
00078         : functor::parameters() {
00079         copy(other);
00080       };
00081 
00082       /**
00083        * destructor
00084        */
00085       ~parameters() {};
00086 
00087       /**
00088        * returns name of this type
00089        */
00090       const char* getTypeName() const {
00091         return "quickMedian<T>::parameters";
00092       };
00093 
00094       /**
00095        * copy the contents of a parameters object
00096        * @param other the parameters object to be copied
00097        * @return a reference to this parameters object
00098        */
00099       parameters& copy(const parameters& other) {
00100 #     ifndef _LTI_MSC_6
00101         // MS Visual C++ 6 is not able to compile this...
00102         functor::parameters::copy(other);
00103 #     else
00104         // ...so we have to use this workaround.
00105         // Conditional on that, copy may not be virtual.
00106         functor::parameters& (functor::parameters::* p_copy)
00107          (const functor::parameters&) =
00108          functor::parameters::copy;
00109         (this->*p_copy)(other);
00110 #     endif
00111 
00112         evenCase = other.evenCase;
00113 
00114         return *this;
00115       };
00116 
00117       /**
00118        * returns a pointer to a clone of the parameters
00119        */
00120       virtual functor::parameters* clone() const {
00121         return new parameters(*this);
00122       };
00123 
00124       /**
00125        * This enum specifies how to consider the case of vectors with
00126        * an even number of elements.
00127        */
00128       enum eEvenCase {
00129         TakeLower, /**< take the element with the lower index, i.e. N/2-1 with
00130                     *   N the number of elements of the vector
00131                     */
00132         TakeHigher /**< take the element with the higher index, i.e. N/2 with
00133                     *   N the number of elements of the vector
00134                     */
00135       };
00136 
00137       /**
00138        * Specifies how to consider the case when the number of elements of
00139        * the vector is even (see eEvenCase).
00140        *
00141        * This parameter has no effect for odd-sized vectors.
00142        *
00143        * Default value: TakeLower
00144        */
00145       eEvenCase evenCase;
00146     };
00147 
00148     /**
00149      * Default constructor
00150      */
00151     quickMedian();
00152 
00153     /**
00154      * Constructor with indicator what to do for even-sized vectors
00155      */
00156     quickMedian(const typename parameters::eEvenCase evenCase);
00157 
00158     /**
00159      * copy constructor
00160      * @param other the object to be copied
00161      */
00162     quickMedian(const quickMedian<T>& other);
00163 
00164     /**
00165      * destructor
00166      */
00167     virtual ~quickMedian();
00168 
00169     /**
00170      * returns the name of this type ("quickMedian")
00171      */
00172     virtual const char* getTypeName() const;
00173 
00174     /**
00175      * operates on the given matrix, which WILL BE modified.
00176      * The resulting matrix contain the elements less or equal than the median
00177      * for the indexes (x,y) such that (x+y*rows() < rows()*columns()/2),
00178      * and higher or equal otherwise.
00179      *
00180      * @param srcdest matrix<T> with the source data.  The result
00181      *                 will be left here too.
00182      * @return the median of the matrix
00183      */
00184     T apply(matrix<T>& srcdest) const;
00185 
00186     /**
00187      * calculates the median of the given matrix, which is NOT modified.
00188      * The elements of the matrix will be considered as part of a vector
00189      * with "columns()" times "rows()" elements.
00190      * @param src matrix<T> with the source data.
00191      * @param dest the median value of the given matrix.
00192      * @return the median of the matrix (as reference to the dest parameter)
00193      */
00194     T& apply(const matrix<T>& src,T& dest) const;
00195 
00196     /**
00197      * operates on the given parameter.
00198      * The resulting vector contains the elements less or equal than the median
00199      * for the indexes <code>x</code> such that <code>x < size()/2</code>,
00200      * and higher or equal otherwise.
00201      *
00202      * @param srcdest vector<T> with the source data.  The result
00203      *                 will be left here too.
00204      * @return a reference to the <code>srcdest</code>.
00205      */
00206     T apply(vector<T>& srcdest) const;
00207 
00208     /**
00209      * operates on the given parameter.
00210      * @param src vector<T> with the source data.
00211      * @param dest the median value
00212      * @return a reference to the <code>dest</code> variable.
00213      */
00214     T& apply(const vector<T>& src, T& dest) const;
00215 
00216     /**
00217      * operates on the given parameter.
00218      * @param src vector<T> with the source data.
00219      * @param dest the partially sorted vector.  The elements at the
00220      *             first half of the vector are less or equal than the median
00221      *             and on the other half greater or equal.
00222      * @param median  the median value
00223      * @return a reference to the <code>median</code> variable.
00224      */
00225     T& apply(const vector<T>& src, vector<T>& dest,T& median) const;
00226 
00227     /**
00228      * operates on the given parameter.
00229      * The resulting vector contains the elements less or equal than the median
00230      * for the indexes <code>x</code> such that <code>x < size()/2</code>,
00231      * and higher or equal otherwise.
00232      *
00233      * @param srcdest vector<T> with the source data.  The result
00234      *                 will be left here too.
00235      * @return the median value.
00236      */
00237     T apply(std::vector<T>& srcdest) const;
00238 
00239     /**
00240      * operates on the given parameter.
00241      * @param src vector<T> with the source data.
00242      * @param dest the median value
00243      * @return a reference to the <code>dest</code> variable.
00244      */
00245     T& apply(const std::vector<T>& src, T& dest) const;
00246 
00247     /**
00248      * operates on the given parameter.
00249      * @param src vector<T> with the source data.
00250      * @param dest the partially sorted vector.  The elements at the
00251      *             first half of the vector are less or equal than the median
00252      *             and on the other half greater or equal.
00253      * @param median  the median value
00254      * @return a reference to the <code>median</code> variable.
00255      */
00256     T& apply(const std::vector<T>& src, std::vector<T>& dest,T& median) const;
00257 
00258     /**
00259      * copy data of "other" functor.
00260      * @param other the functor to be copied
00261      * @return a reference to this functor object
00262      */
00263     quickMedian& copy(const quickMedian& other);
00264 
00265     /**
00266      * returns a pointer to a clone of this functor.
00267      */
00268     virtual functor* clone() const;
00269 
00270     /**
00271      * returns used parameters
00272      */
00273     const parameters& getParameters() const;
00274 
00275   protected:
00276     /**
00277      * this method calculates the median in a recursively form
00278      */
00279     T  findMedian(vector<T>& vct,
00280                   const int& begin,
00281                   const int& end,
00282                   const int& medianPos) const;
00283     
00284     /**
00285      * this method chooses a pivot-value and ensures that lower values lie
00286      * at the left and higher values at the right of its final position, which
00287      * will be returned.
00288      */
00289     int partition(vector<T>& vct,
00290                   const int& begin,
00291                   const int& end) const;
00292 
00293     /**
00294      * this method calculates the median in a recursively form
00295      */
00296     T  findMedian(std::vector<T>& vct,
00297                   const int& begin,
00298                   const int& end,
00299                   const int& medianPos) const;
00300     
00301     /**
00302      * this method chooses a pivot-value and ensures that lower values lie
00303      * at the left and higher values at the right of its final position, which
00304      * will be returned.
00305      */
00306     int partition(std::vector<T>& vct,
00307                   const int& begin,
00308                   const int& end) const;
00309 
00310   };
00311 
00312   /**
00313    * This class is used to extract the median of the elements of a
00314    * given vector or matrix, partitioning at the same time a second
00315    * vector.  The median is defined as the element at the middle
00316    * position of the sorted vector.  The algorithm used is based on
00317    * the quick sort.
00318    *
00319    * The difference with the lti::quickMedian functor is that you can
00320    * "sort" a second vector, which might contain for example the indices
00321    * of the elements.  This way, you can easily find out, which elements of the
00322    * original vector are under the median, and which ones above.
00323    *
00324    * @see lti::quickMedian, lti::sort, lti::sort2
00325    *
00326    * For vectors (or matrices) with an even number n of elements, the
00327    * median will be the element at (n/2) or (n/2)-1 depending on the
00328    * parameter settings.
00329    *
00330    * The type of the vector elements (T) must accept the operators <
00331    * and >.
00332    *
00333    * @ingroup gStats
00334    */
00335   template <class T,class U>
00336   class quickMedian2 : public quickMedian<T> {
00337   public:
00338     
00339     typedef typename quickMedian<T>::parameters parameters;
00340 
00341     /**
00342      * default constructor
00343      */
00344     quickMedian2();
00345 
00346     /**
00347      * copy constructor
00348      * @param other the object to be copied
00349      */
00350     quickMedian2(const quickMedian2<T,U>& other);
00351 
00352     /**
00353      * destructor
00354      */
00355     virtual ~quickMedian2();
00356 
00357     /**
00358      * returns the name of this type ("quickMedian2")
00359      */
00360     virtual const char* getTypeName() const;
00361 
00362     /**
00363      * operates on the given parameter.
00364      * The resulting keys vector contains the elements less or equal than the
00365      * median for the indexes <code>x</code> such that 
00366      * <code>x < size()/2</code>, and higher or equal otherwise.
00367      *
00368      * Both vectors must have the same size.
00369      *
00370      * @param keys vector<T> with the key data.  The median of this data
00371      *             is partially sorted while looking for the median.
00372      * @param data vector<U> with data to be sorted the same way as the keys.
00373      *             You can for example use a ivector initialized with the
00374      *             index values (i.e. data(i)=i), so that after the apply
00375      *             method you can check which elements are below the median
00376      *             and which above.
00377      *             
00378      * @return a the median value of keys.
00379      */
00380     T apply(vector<T>& keys,vector<U>& data) const;
00381 
00382     /**
00383      * returns a pointer to a clone of this functor.
00384      */
00385     virtual functor* clone() const;
00386 
00387   protected:
00388     /**
00389      * this method calculates the median in a recursively form
00390      */
00391     T  findMedian(vector<T>& vct,
00392                   vector<U>& data,
00393                   const int& begin,
00394                   const int& end,
00395                   const int& medianPos) const;
00396     
00397     /**
00398      * this method chooses a pivot-value and ensures that lower values lie
00399      * at the left and higher values at the right of its final position, which
00400      * will be returned.
00401      */
00402     int partition(vector<T>& vct,
00403                   vector<U>& data,
00404                   const int& begin,
00405                   const int& end) const;
00406   };
00407 
00408 
00409 
00410 }
00411 
00412 #include "ltiQuickMedian_template.h"
00413 
00414 #endif

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