contrib/mul/mbl/mbl_clusters.h
Go to the documentation of this file.
00001 #ifndef mbl_clusters_h_
00002 #define mbl_clusters_h_
00003 //:
00004 // \file
00005 // \brief  Class to record clusters of data, for faster neighbour finding
00006 // \author Tim Cootes
00007 
00008 #include <vcl_vector.h>
00009 #include <vcl_iostream.h>
00010 #include <vsl/vsl_fwd.h>
00011 
00012 //:  Class to record clusters of data, for faster neighbour finding
00013 //  Used to record clusters of objects of type T.
00014 //  D::d(T t1, T t2) is a measure of distance between two objects.
00015 //  It must obey the triangle inequality:
00016 //  D::d(t1,t2)<=D::d(t1,t3)+D::d(t2,t3).
00017 //
00018 //  Pointer retained to an external vector of objects.  The class
00019 //  is designed to allow fast location of the nearest of the external
00020 //  objects to a given new object.  It represents the data as a
00021 //  set of key point positions, together with a list of indices into
00022 //  the external data for each cluster.
00023 //
00024 //  Thus to find the nearest neighbour, we first check for proximity
00025 //  to the keypoints, and only consider objects in the clusters
00026 //  which are sufficiently close.
00027 template<class T, class D>
00028 class mbl_clusters
00029 {
00030  private:
00031   //: Pointer to external list of objects
00032   const vcl_vector<T>* data_;
00033 
00034   //: Cluster key point
00035   vcl_vector<T> p_;
00036 
00037   //: Maximum radius for any cluster
00038   double max_r_;
00039 
00040   //: Indices of objects associated with each cluster
00041   vcl_vector<vcl_vector<unsigned> > index_;
00042 
00043   //: Furthest distance of a cluster object from key point for cluster
00044   vcl_vector<double> r_;
00045 
00046  public:
00047   mbl_clusters();
00048 
00049   //: Empty clusters
00050   void empty();
00051 
00052   //: Define maximum radius for each cluster
00053   void set_max_r(double r);
00054 
00055   //: Define external data array (pointer retained)
00056   //  Empty existing clusters, then process every element of data
00057   //  to create clusters, by calling add_object()
00058   void set_data(const vcl_vector<T>& data);
00059 
00060   //: Define external data array (pointer retained)
00061   //  Use carefully! This sets the internal pointer to
00062   //  point to data.  Really only to be used after loading
00063   //  internals using b_read(bfs).
00064   void set_data_ptr(const vcl_vector<T>& data);
00065 
00066   //: External list of objects
00067   const vcl_vector<T>& data() const { return *data_; }
00068 
00069   //: Maximum radius for any cluster
00070   double max_r() const { return max_r_; }
00071 
00072   //: Cluster key points
00073   const vcl_vector<T>& p() const { return p_; }
00074 
00075   //: Number of clusters
00076   unsigned n_clusters() const { return p_.size(); }
00077 
00078   //: Furthest distance of a cluster object from key point for cluster
00079   const vcl_vector<double>& r() const { return r_; }
00080 
00081   //: Indices of objects associated with each cluster
00082   const vcl_vector<vcl_vector<unsigned> >& index() const
00083    { return index_; }
00084 
00085   //: Set given radius
00086   void set_r(unsigned i, double r) { r_[i]=r; }
00087 
00088   //: Return index of nearest object in data() to t
00089   //  Nearest object in data() to t is given by data()[nearest(t,d)];
00090   //  The distance to the point is d
00091   unsigned nearest(const T& t, double& d) const;
00092 
00093   //: Return index of nearest object in data() to t
00094   //  Consider only objects in clusters given in c_list
00095   //  Nearest object in data() to t is given by data()[nearest(t,d)];
00096   //  The distance to the point is d
00097   unsigned nearest(const T& t, double& d,
00098                    const vcl_vector<unsigned>& c_list) const;
00099 
00100   //: Return index of nearest cluster in data() to t
00101   //  Finds nearest cluster key point to t
00102   //  The distance to the point is d
00103   unsigned nearest_cluster(const T& t, double& d) const;
00104 
00105   //: Return indices of clusters which may contain nearest point to t
00106   //  Searches through all the clusters, returning list in near_c
00107   void nearest_clusters(const T& t, double& max_d,
00108                         vcl_vector<unsigned>& near_c) const;
00109 
00110   //: Return indices of clusters which may contain nearest point to t
00111   //  Searches through clusters listed in c_list.
00112   //  On input, max_d gives initial limit on distance.
00113   //  On exit, max_d gives the revised limit on the distance
00114   void nearest_clusters(const T& t, double& max_d,
00115                         const vcl_vector<unsigned>& c_list,
00116                         vcl_vector<unsigned>& near_c) const;
00117 
00118   //: Append new object with index i and assign to a cluster
00119   //  Assumes that new object data()[i] is available.
00120   //  Deduce which cluster it belongs to and add it.
00121   //  Create new cluster if further than max_r() from any.
00122   //  r is the radius associated with data()[i], which is
00123   //  zero for a single point, but non-zero when the point
00124   //  is itself a key point for a cluster (eg in mbl_cluster_tree)
00125   //  Return index of cluster it is assigned to
00126   unsigned add_object(unsigned i, double r=0.0);
00127 
00128   //: Create a new cluster around point data()[i]
00129   //  Assumes that new object data()[i] is available.
00130   //  Return index of cluster
00131   unsigned create_cluster(unsigned i, double r=0.0);
00132 
00133   //: Assign object data()[i] to cluster ci, knowing distance r.
00134   //  r is the distance D::d(data()[i],p()[ci])
00135   void assign_to_cluster(unsigned i, unsigned ci, double r);
00136 
00137   //: Finds list of clusters whose keypoint is within d of t
00138   //  Returns number of such clusters. If >0, then nearest_c
00139   //  gives index of cluster with centre nearest to t
00140   unsigned clusters_within_d(const T& t, double d,
00141                              vcl_vector<unsigned>& c_list,
00142                              unsigned& nearest_c,
00143                              double& min_d);
00144 
00145   //: Finds list of clusters whose keypoint is within max_r of t
00146   //  Returns number of such clusters. If >0, then nearest_c
00147   //  gives index of cluster with centre nearest to t
00148   unsigned clusters_within_max_r(const T& t,
00149                                  vcl_vector<unsigned>& c_list,
00150                                  unsigned& nearest_c,
00151                                  double& min_d);
00152 
00153   //: Finds list of clusters whose keypoint is within d of t
00154   //  Only considers subset of clusters listed in in_list
00155   //  Returns number of such clusters. If >0, then nearest_c
00156   //  gives index of cluster with centre nearest to t
00157   unsigned clusters_within_d(const T& t, double d,
00158                              const vcl_vector<unsigned>& in_list,
00159                              vcl_vector<unsigned>& c_list,
00160                              unsigned& nearest_c,
00161                              double& min_d);
00162 
00163   //: Finds list of clusters whose keypoint is within max_r of t
00164   //  Only considers subset of clusters listed in index
00165   //  Returns number of such clusters. If >0, then nearest_c
00166   //  gives index of cluster with centre nearest to t
00167   unsigned clusters_within_max_r(const T& t,
00168                              const vcl_vector<unsigned>& in_list,
00169                              vcl_vector<unsigned>& c_list,
00170                              unsigned& nearest_c,
00171                              double& min_d);
00172 
00173   //: Create list of object indices in listed clusters
00174   //  Concatenates lists of indices for each cluster in c_list
00175   void in_clusters(const vcl_vector<unsigned>& c_list,
00176                    vcl_vector<unsigned>& o_list) const;
00177 
00178   //: Write out list of elements in each cluster
00179   void print_cluster_sets(vcl_ostream& os) const;
00180 
00181   //: Version number for I/O
00182   short version_no() const;
00183 
00184   //: Print class to os
00185   void print_summary(vcl_ostream& os) const;
00186 
00187   //: Save class to binary file stream.
00188   //  Warning: Does not save external data - that must
00189   //  be recorded separately.
00190   void b_write(vsl_b_ostream& bfs) const;
00191 
00192   //: Load class from binary file stream
00193   //  Warning: Does not load or link external data - that must
00194   //  be recorded separately, then connected using set_data_ptr()
00195   void b_read(vsl_b_istream& bfs);
00196 };
00197 
00198 //: Binary file stream output operator for class reference
00199 template<class T, class D>
00200 void vsl_b_write(vsl_b_ostream& bfs, const mbl_clusters<T,D>& c);
00201 
00202 //: Binary file stream input operator for class reference
00203 template<class T, class D>
00204 void vsl_b_read(vsl_b_istream& bfs, mbl_clusters<T,D>& c);
00205 
00206 //: Stream output operator for class reference
00207 template<class T, class D>
00208 vcl_ostream& operator<<(vcl_ostream& os,const mbl_clusters<T,D>& c);
00209 
00210 #endif // mbl_clusters_h_