Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

GenKMeans.H

Go to the documentation of this file.
00001  /*---------------------------------------------------------------------+
00002  | Library QgarLib, graphics analysis and recognition                  |
00003  | Copyright (C) 2002  Qgar Project, LORIA                             |
00004  |                                                                     |
00005  | This library is free software; you can redistribute it and/or       |
00006  | modify it under the terms of the GNU Lesser General Public          |
00007  | License version 2.1, as published by the Free Software Foundation.  |
00008  |                                                                     |
00009  | This library is distributed in the hope that it will be useful,     |
00010  | but WITHOUT ANY WARRANTY; without even the implied warranty of      |
00011  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                |
00012  | See the GNU Lesser General Public License for more details.         |
00013  |                                                                     |
00014  | The GNU Lesser General Public License is included in the file       |
00015  | LICENSE.LGPL, in the root directory of the Qgar packaging. See      |
00016  | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. |
00017  | To receive a paper copy, write to the Free Software Foundation,     |
00018  | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.       |
00019  |                                                                     |
00020  | Contact Project Qgar for any information:                           |
00021  |   LORIA - équipe Qgar                                               |
00022  |   B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France                |
00023  |   email: qgar-contact@loria.fr                                      |
00024  |   http://www.qgar.org/                                              |
00025  *---------------------------------------------------------------------*/
00026 
00027 
00028 #ifndef __GENKMEANS_H_INCLUDED__
00029 #define __GENKMEANS_H_INCLUDED__
00030 
00031 
00032 /**
00033  * @file     GenKMeans.H
00034  * @brief    Header file of classes qgar::GenCluster and qgar::GenKMeans.
00035  *
00036  * @author   <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00037  * @date     July 3, 2001  15:57
00038  * @since    Qgar 2.1
00039  */
00040 
00041 
00042 // For RCS/CVS use: Do not delete
00043 /* $Id: GenKMeans.H,v 1.26 2005/10/14 17:05:46 masini Exp $ */
00044 
00045 
00046 
00047 // STD
00048 #include <vector>
00049 // QGAR
00050 #include <qgarlib/QgarErrorAlgorithm.H>
00051 
00052 
00053 
00054 namespace qgar
00055 {
00056 
00057 
00058 /*---------------------------------------------------------------------*
00059  |                                                                     |
00060  |          C  L  A  S  S      G  E  N  C  L  U  S  T  E  R            |
00061  |                                                                     |
00062  *---------------------------------------------------------------------*/
00063 
00064 /**
00065  * @ingroup TOOL_CLASSIF
00066  *
00067  * @class GenCluster GenKMeans.H
00068  *
00069  * @brief A cluster, as generated by the k-means algorithm implemented
00070  *        by class qgar::GenKMeans.
00071  *
00072  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Jan Rendek">Jan Rendek</a>
00073  * @date   Apr 2, 2004  08:36
00074  * @since  Qgar 2.1.1
00075  */
00076 template <class T> class GenCluster
00077 {
00078 // -------------------------------------------------------------------
00079 // T Y P E   D E F I N I T I O N S
00080 // -------------------------------------------------------------------
00081 public:
00082 
00083   /** @name Types */
00084   //        =====
00085   //@{
00086 
00087   /**
00088    * @brief Type of the cluster elements.
00089    */
00090   typedef T value_type;
00091 
00092   /**
00093    * @brief Reference to qgar::GenCluster::value_type.
00094    */
00095   typedef value_type& reference;
00096 
00097   /**
00098    * @brief Constant reference to qgar::GenCluster::value_type.
00099    */
00100   typedef const value_type& const_reference;
00101 
00102   /**
00103    * @brief Pointer to qgar::GenImage::value_type.
00104    */
00105   typedef value_type* pointer;
00106 
00107   /**
00108    * @brief Constant pointer to qgar::GenCluster::value_type.
00109    */
00110   typedef const value_type* const_pointer;
00111 
00112   //@}
00113 
00114 // -------------------------------------------------------------------
00115 // P U B L I C    M E M B E R S
00116 // -------------------------------------------------------------------
00117 public:
00118 
00119   /** @name Constructors */
00120   //        ============
00121   //@{
00122 
00123   /**
00124    * @brief Builds a cluster.
00125    *
00126    * @param elements  the elements of the cluster
00127    * @param center    the center of the cluster
00128    */
00129   GenCluster(const std::vector<value_type>& elements,
00130              const_reference center);
00131 
00132   /**
00133    * @brief Copy constructor.
00134    *
00135    * @param other the instance to be copied
00136    */
00137   GenCluster(const GenCluster& other);
00138 
00139   //@}
00140 
00141 
00142   /** @name Operators */
00143   //        =========
00144   //@{
00145 
00146   /**
00147    * @brief Assignment operator.
00148    *
00149    * @param rhs The rhs part of the assignment
00150    */
00151   GenCluster& operator=(const GenCluster& rhs);
00152 
00153   //@}
00154 
00155 
00156   /** @name Access */
00157   //        ======
00158   //@{
00159 
00160   /**
00161    * @brief Retrieves the size of the cluster.
00162    *
00163    * @return The size of the cluster
00164    */
00165   inline size_t size() const;
00166 
00167   /**
00168    * @brief Retrieves the center of the cluster.
00169    *
00170    * @return the center of the cluster
00171    */
00172   inline const_reference center() const;
00173 
00174   /**
00175    * @brief Retrieves the elements composing the cluster.
00176    *
00177    * @return a reference to the vector containing the elements
00178    *   of this cluster
00179    */
00180   inline const std::vector<value_type>& elements() const;
00181 
00182   //@}
00183  
00184 // -------------------------------------------------------------------
00185 // P R I V A T E    M E M B E R S
00186 // -------------------------------------------------------------------
00187 private:
00188 
00189   /** @name Cluster features */
00190   //        ================
00191   //@{
00192 
00193   /**
00194    * @brief The center of the cluster.
00195    */
00196   value_type _center;
00197   
00198   /**
00199    * @brief The elements of the cluster.
00200    */
00201   std::vector<value_type> _elements;
00202 
00203   //@}
00204 
00205 
00206 // -------------------------------------------------------------------
00207 }; // class GenCluster
00208 
00209 
00210 
00211 
00212 
00213 /*---------------------------------------------------------------------*
00214  |                                                                     |
00215  |            C  L  A  S  S      G  E  N  K  M  E  A  N  S             |
00216  |                                                                     |
00217  *---------------------------------------------------------------------*/
00218 
00219 
00220 /**
00221  * @ingroup TOOL_CLASSIF
00222  *
00223  * @class GenKMeans GenKMeans.H "qgarlib/GenKMeans.H"
00224  *
00225  * @brief Template class for partitioning a list of objects of type
00226  * <b>T</b> into a (given) number of clusters using a k-means algorithm.
00227  *
00228  * @warning The class is not supposed to be derived: The destructor
00229  * (as any other function) is not virtual.
00230  *
00231  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00232  * @date   July 3, 2001  15:57
00233  * @since  Qgar 2.1
00234  */
00235 template <class T> class GenKMeans
00236 {
00237 // -------------------------------------------------------------------
00238 // D E F I N I T I O N S
00239 // -------------------------------------------------------------------
00240 public:
00241 
00242   /** @name Types */
00243   //        =====
00244   //@{
00245 
00246   /**
00247    * @brief Type of the objects to be partitioned.
00248    */
00249   typedef T value_type;
00250 
00251   /**
00252    * @brief Reference to qgar::GenKMeans::value_type.
00253    */
00254   typedef value_type& reference;
00255 
00256   /**
00257    * @brief Constant reference to qgar::GenKMeans::value_type.
00258    */
00259   typedef const value_type& const_reference;
00260 
00261   /**
00262    * @brief Pointer to qgar::GenKMeans::value_type.
00263    */
00264   typedef value_type* pointer;
00265 
00266   /**
00267    * @brief Constant pointer to qgar::GenKMeans::value_type.
00268    */
00269   typedef const value_type* const_pointer;
00270 
00271   //@}
00272 
00273 
00274   /** @name Signatures */
00275   //        ==========
00276   //@{
00277 
00278   /**
00279    * @brief Signature of the distance function.
00280    */
00281   typedef double (*DistanceFunction) (const_reference, const_reference);
00282 
00283   //@}
00284 
00285 
00286 // -------------------------------------------------------------------
00287 // P U B L I C    M E M B E R S
00288 // -------------------------------------------------------------------
00289 public:
00290 
00291 
00292   /** @name Constructors */
00293   //        ============
00294   //@{
00295 
00296   /**
00297    * @brief Construct a partition of clusters using a distance function.
00298    *
00299    * @param anObjVect      vector of the objects to be partitioned
00300    * @param aDistFunction  distance function <b>f(T*,T*)</b>
00301    * @param aClusterCnt    number of resulting clusters (default <b>3</b>)
00302    *
00303    * @throw qgar::QgarErrorAlgorithm
00304    *   if an error occurred while creating clusters
00305    */
00306   GenKMeans(const std::vector<value_type>& anObjVect,
00307             DistanceFunction aDistFunction,
00308             int aClusterCnt = 3)
00309     throw(qgar::QgarErrorAlgorithm);
00310 
00311   /**
00312    * @brief Construct a partition of clusters of given centers,
00313    *   using a distance function.
00314    *
00315    * @param anObjVect      vector of the objects to be partitioned
00316    * @param aDistFunction  distance function <b>f(T*,T*)</b>
00317    * @param aCenterVector  vector of the initial centers of the clusters
00318    * @param aClusterCnt    number of resulting clusters (default <b>3</b>)
00319    *
00320    * @throw qgar::QgarErrorAlgorithm
00321    *   if an error occurred while creating clusters
00322    */
00323   GenKMeans(const std::vector<value_type>& anObjVect,
00324             DistanceFunction aDistFunction,         
00325             const std::vector<value_type>& aCenterVector,
00326             int aClusterCnt = 3)
00327     throw(qgar::QgarErrorAlgorithm);
00328 
00329   //@}
00330 
00331 
00332   /** @name Destructor */
00333   //        ==========
00334   //@{
00335 
00336   /**
00337    * @brief Destructor.
00338    *
00339    * It is not virtual as the class is not supposed to be derived.
00340    */
00341   ~GenKMeans();
00342 
00343   //@}
00344 
00345 
00346   /** @name Access */
00347   //        ======
00348   //@{
00349 
00350   /**
00351    * @brief Get number of resulting clusters.
00352    */
00353   inline int clusterCnt() const;
00354 
00355   /**
00356    * @brief Get the vector storing the resulting cluster sizes.
00357    */
00358   inline const std::vector<int>& clusterSizes() const;
00359 
00360   /** 
00361    *@brief Get the vector storing the resulting cluster centers.
00362    */
00363   inline const std::vector<const_pointer>& clusterCenters() const;
00364 
00365   /**
00366    * @brief Get the vector storing the elements of the clusters.
00367    *
00368    * Each element of the returned vector represents a cluster.
00369    * Each cluster is itself represented by a vector, storing
00370    * pointers to the elements of the cluster.
00371    */
00372   inline const std::vector< std::vector<const_pointer> >&
00373   accessClusterElts() const;
00374 
00375   /**
00376    * @brief Get a copy of the vector storing the elements
00377    *   of the clusters.
00378    *
00379    * Each element of the returned vector represents a cluster.
00380    * Each cluster is itself represented by a vector, storing
00381    * pointers to the elements of the cluster.
00382    */
00383   inline std::vector< std::vector<const_pointer> >
00384   clusterElts() const;
00385 
00386   /**
00387    * @brief Get the vector storing the clusters.
00388    *
00389    * Each element of the returned vector represents a cluster.
00390    * Each cluster is represented by an instance of class
00391    * qgar::GenCluster.
00392    */
00393   const std::vector< GenCluster<value_type> >&
00394   accessClusters() const;
00395 
00396   /**
00397    * @brief Get a copy of the vector storing the clusters.
00398    *
00399    * Each element of the returned vector represents a cluster.
00400    * Each cluster is represented by an instance of class
00401    * qgar::GenCluster.
00402    */
00403   std::vector< GenCluster<value_type> > clusters() const;
00404 
00405   //@}
00406 
00407 // -------------------------------------------------------------------
00408 // P R O T E C T E D    M E M B E R S
00409 // -------------------------------------------------------------------
00410 protected:
00411 
00412   /** @name Representation of a cluster */
00413   //        ===========================
00414   //@{
00415 
00416   /**
00417    * @brief Number of clusters.
00418    */
00419   const int _clusterCnt;
00420 
00421   /**
00422    * @brief Vector storing the values of the clusters.
00423    *
00424    * Each element of this vector represents a cluster.
00425    * Each cluster is also represented by a vector, storing the pointers
00426    * to the elements of the cluster.
00427    */
00428   std::vector< std::vector<const_pointer> > _clusterElts;
00429 
00430   /**
00431    * @brief Vector of clusters sizes.
00432    */
00433   std::vector<int> _clusterSizes;
00434 
00435   /**
00436    * @brief Vector of cluster centers.
00437    */
00438   std::vector<const_pointer> _clusterCenters;
00439 
00440   /**
00441    * @brief Vector of objects to be partitioned.
00442    */
00443   std::vector<const_pointer> _objVect;
00444 
00445   /**
00446    * @brief Vector storing the final clusters.
00447    *
00448    * Each element of this vector represents a cluster.
00449    * Each cluster is represented by an instance
00450    * of class qgar::GenCluster.
00451    */
00452   mutable std::vector< GenCluster<value_type> > _clusters;
00453 
00454   /**
00455    * @brief The distance function.
00456    */
00457   const DistanceFunction _distance;
00458 
00459   //@}
00460 
00461 // -------------------------------------------------------------------
00462 // P R I V A T E    M E M B E R S
00463 // -------------------------------------------------------------------
00464 private:
00465 
00466   /** @name Auxiliaries */
00467   //        ===========
00468   //@{
00469 
00470   /**
00471    * @brief Initialize cluster centers.
00472    *
00473    * Use a given number of the first objects of the given list of objects.
00474    *
00475    * @exception qgar::QgarErrorAlgorithm
00476    */
00477   void PRIVATEinitCenters()  throw(qgar::QgarErrorAlgorithm);
00478 
00479   /**
00480    * @brief Distribute objects into clusters.
00481    */
00482   void PRIVATEdistributeIntoClusters();
00483 
00484   /**
00485    * @brief Compute new cluster centers.
00486    *
00487    * @param aNewCenterVector  vector of resulting cluster centers
00488    *
00489    * @exception qgar::QgarErrorAlgorithm
00490    */
00491   void PRIVATEgetCenters(std::vector<const_pointer>& aNewCenterVector)
00492     throw(qgar::QgarErrorAlgorithm);
00493 
00494   /**
00495    * @brief Loop on constructing clusters until getting stable centers.
00496    */
00497   void PRIVATEgetClusters();
00498 
00499   /**
00500    * @brief Construct the final clusters in <b>_clusters</b>
00501    *   from <b>_clustersElts</b>.
00502    */
00503   void PRIVATEconsFinalClusters();
00504 
00505   //@}
00506 
00507 
00508   /** @name Disabled */
00509   //        ========
00510   //@{
00511 
00512   /**
00513    * @brief Disabled copy constructor.
00514    */
00515   GenKMeans(const GenKMeans&);
00516 
00517   /**
00518    * @brief Disabled assignment operator.
00519    */
00520   GenKMeans& operator=(const GenKMeans&);
00521 
00522   //@}
00523 
00524 // ---------------------------------------------------------------------
00525 
00526 }; // class GenKmeans
00527 
00528 
00529 } // namespace qgar
00530 
00531 
00532 
00533 
00534 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00535 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00536 // I M P L E M E N T A T I O N
00537 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00538 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00539 
00540 
00541 #include <qgarlib/GenKMeans.TCC>
00542 
00543 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00544 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00545 
00546 
00547 
00548 
00549 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
00550 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
00551 // H  E  L  P  E  R  S
00552 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
00553 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
00554 
00555 
00556 namespace qgar
00557 {
00558 
00559 
00560 /** @name KMeans helper functions  */
00561 //        =======================
00562 //@{
00563 
00564 /**
00565  * @ingroup GLOB_HELPER
00566  *
00567  * @brief Construct a partition of clusters using a distance function.
00568  *
00569  * @param anObjVect     vector of objects to be partitioned
00570  * @param aDistFunction distance function <b>f(const T&, const T&)</b>
00571  * @param aClusterCnt   number of resulting clusters (default <b>3</b>)
00572  *
00573  * @throw qgar::QgarErrorAlgorithm
00574  *   if an error occurred while creating clusters
00575  */
00576 template <class T>
00577 std::vector< GenCluster<T> > 
00578 qgKMeans(const std::vector<T>& anObjVect,
00579          double (*aDistFunction) (const T&, const T&),
00580          int aClusterCnt = 3)
00581 
00582   throw (QgarErrorAlgorithm);
00583 
00584 
00585 /**
00586  * @ingroup GLOB_HELPER
00587  *
00588  * @brief Construct a partition of clusters of given centers,
00589  *   using a distance function.
00590  *
00591  * @param anObjVect     vector of objects to be partitioned
00592  * @param aDistFunction distance function <b>f(const T&, const T&)</b>
00593  * @param aCenterVector vector of the initial centers of the clusters
00594  * @param aClusterCnt   number of resulting clusters (default <b>3</b>)
00595  *
00596  * @throw qgar::QgarErrorAlgorithm
00597  *   if an error occurred while creating clusters
00598  */
00599 template <class T>
00600 std::vector< GenCluster<T> >
00601 qgKMeans(const std::vector<T>& anObjVect,
00602          double (*aDistFunction) (const T&, const T&),
00603          std::vector<T*>& aCenterVector,
00604          int aClusterCnt = 3)
00605 
00606   throw (QgarErrorAlgorithm);
00607 
00608 //@}
00609 
00610 
00611 } // namespace qgar 
00612 
00613 
00614 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
00615 // HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
00616 
00617 
00618 #endif /* __GENKMEANS_H_INCLUDED__ */