ClosestPair2D.hh

00001 //STARTHEADER
00002 // $Id: ClosestPair2D.hh 1761 2010-09-16 10:43:18Z soyez $
00003 //
00004 // Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam
00005 //
00006 //----------------------------------------------------------------------
00007 // This file is part of FastJet.
00008 //
00009 //  FastJet is free software; you can redistribute it and/or modify
00010 //  it under the terms of the GNU General Public License as published by
00011 //  the Free Software Foundation; either version 2 of the License, or
00012 //  (at your option) any later version.
00013 //
00014 //  The algorithms that underlie FastJet have required considerable
00015 //  development and are described in hep-ph/0512210. If you use
00016 //  FastJet as part of work towards a scientific publication, please
00017 //  include a citation to the FastJet paper.
00018 //
00019 //  FastJet is distributed in the hope that it will be useful,
00020 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022 //  GNU General Public License for more details.
00023 //
00024 //  You should have received a copy of the GNU General Public License
00025 //  along with FastJet; if not, write to the Free Software
00026 //  Foundation, Inc.:
00027 //      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028 //----------------------------------------------------------------------
00029 //ENDHEADER
00030 
00031 #ifndef __FASTJET_CLOSESTPAIR2D__HH__
00032 #define __FASTJET_CLOSESTPAIR2D__HH__
00033 
00034 #include<vector>
00035 #include<stack>
00036 #include<iostream>
00037 #include "fastjet/internal/ClosestPair2DBase.hh"
00038 #include "fastjet/internal/SearchTree.hh"
00039 #include "fastjet/internal/MinHeap.hh"
00040 
00041 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
00042 
00043 //----------------------------------------------------------------------
00050 class ClosestPair2D : public ClosestPair2DBase {
00051 public:
00056   ClosestPair2D(const std::vector<Coord2D> & positions, 
00057                 const Coord2D & left_corner, const Coord2D & right_corner) {
00058     _initialize(positions, left_corner, right_corner, positions.size());
00059   };
00060 
00063   ClosestPair2D(const std::vector<Coord2D> & positions, 
00064                 const Coord2D & left_corner, const Coord2D & right_corner,
00065                 const unsigned int max_size) {
00066     _initialize(positions, left_corner, right_corner, max_size);
00067   };
00068 
00071   void closest_pair(unsigned int & ID1, unsigned int & ID2, 
00072                     double & distance2) const;
00073 
00075   void remove(unsigned int ID);
00076  
00079   unsigned int insert(const Coord2D &);
00080 
00083   virtual unsigned int replace(unsigned int ID1, unsigned int ID2, 
00084                                const Coord2D & position);
00085 
00088   virtual void replace_many(const std::vector<unsigned int> & IDs_to_remove,
00089                             const std::vector<Coord2D> & new_positions,
00090                             std::vector<unsigned int> & new_IDs);
00091 
00092   // mostly for checking how things are working...
00093   inline void print_tree_depths(std::ostream & outdev) const {
00094     outdev    << _trees[0]->max_depth() << " "
00095               << _trees[1]->max_depth() << " "
00096               << _trees[2]->max_depth() << "\n";
00097   };
00098 
00099   unsigned int size();
00100 
00101 private:
00102   
00103   void _initialize(const std::vector<Coord2D> & positions, 
00104               const Coord2D & left_corner, const Coord2D & right_corner,
00105               const unsigned int max_size);
00106 
00107   static const unsigned int _nshift = 3;
00108 
00109   class Point; // will be defined below
00110 
00113   template<class T> class triplet {
00114   public:
00115     inline const T & operator[](unsigned int i) const {return _contents[i];};
00116     inline       T & operator[](unsigned int i)       {return _contents[i];};
00117   private:
00118     T _contents[_nshift];
00119   };
00120 
00121 
00123   class Shuffle {
00124   public:
00125     unsigned int x, y;
00126     Point * point;
00127     bool operator<(const Shuffle &) const;
00128     void operator+=(unsigned int shift) {x += shift; y+= shift;};
00129   };
00130 
00131   typedef SearchTree<Shuffle>     Tree;
00132   typedef Tree::circulator        circulator;
00133   typedef Tree::const_circulator  const_circulator;
00134 
00135 
00136   triplet<std::auto_ptr<Tree> >  _trees;
00137   std::auto_ptr<MinHeap> _heap;
00138   std::vector<Point>     _points;
00139   std::stack<Point *>    _available_points;
00140 
00142   std::vector<Point *>   _points_under_review;
00143 
00144   // different statuses for review
00145   static const unsigned int _remove_heap_entry = 1;
00146   static const unsigned int _review_heap_entry = 2;
00147   static const unsigned int _review_neighbour  = 4;
00148 
00152   void _add_label(Point * point, unsigned int review_flag);
00153 
00157   void _set_label(Point * point, unsigned int review_flag);
00158 
00163   void _deal_with_points_to_review();
00164 
00166   void _remove_from_search_tree(Point * point_to_remove);
00167 
00169   void _insert_into_search_tree(Point * new_point);
00170 
00172   void _point2shuffle(Point & , Shuffle & , unsigned int shift);
00173 
00175   Coord2D _left_corner;
00176   double _range;
00177 
00178   int _ID(const Point *) const;
00179 
00180   triplet<unsigned int> _shifts;     // absolute shifts
00181   triplet<unsigned int> _rel_shifts; // shifts relative to previous shift
00182 
00183   unsigned int _cp_search_range;
00184 };
00185 
00186 
00187 //----------------------------------------------------------------------
00193 class ClosestPair2D::Point {
00194 public:
00196   Coord2D coord;
00198   Point * neighbour;
00200   double  neighbour_dist2;
00202   triplet<circulator> circ;
00203 
00205   unsigned int review_flag;
00206 
00208   double distance2(const Point & other) const {
00209     return coord.distance2(other.coord);
00210   };
00211 
00213   //void set_shuffle(Shuffle & shuffle);
00214 };
00215 
00216 
00217 //----------------------------------------------------------------------
00220 inline bool floor_ln2_less(unsigned x, unsigned y) {
00221   if (x>y) return false;
00222   return (x < (x^y)); // beware of operator precedence...
00223 }
00224 
00225 
00226 //----------------------------------------------------------------------
00228 inline int ClosestPair2D::_ID(const Point * point) const {
00229   return point - &(_points[0]);
00230 }
00231 
00232 
00233 //
00234 inline unsigned int ClosestPair2D::size() {
00235   return _points.size() - _available_points.size();
00236 }
00237 
00238 
00239 
00240 FASTJET_END_NAMESPACE
00241 
00242 #endif // __FASTJET_CLOSESTPAIR2D__HH__