31 #ifndef __FASTJET_CLOSESTPAIR2D__HH__
32 #define __FASTJET_CLOSESTPAIR2D__HH__
37 #include "fastjet/internal/ClosestPair2DBase.hh"
38 #include "fastjet/internal/SearchTree.hh"
39 #include "fastjet/internal/MinHeap.hh"
41 FASTJET_BEGIN_NAMESPACE
50 class ClosestPair2D :
public ClosestPair2DBase {
56 ClosestPair2D(
const std::vector<Coord2D> & positions,
57 const Coord2D & left_corner,
const Coord2D & right_corner) {
58 _initialize(positions, left_corner, right_corner, positions.size());
63 ClosestPair2D(
const std::vector<Coord2D> & positions,
64 const Coord2D & left_corner,
const Coord2D & right_corner,
65 const unsigned int max_size) {
66 _initialize(positions, left_corner, right_corner, max_size);
71 void closest_pair(
unsigned int & ID1,
unsigned int & ID2,
72 double & distance2)
const;
75 void remove(
unsigned int ID);
79 unsigned int insert(
const Coord2D &);
83 virtual unsigned int replace(
unsigned int ID1,
unsigned int ID2,
84 const Coord2D & position);
88 virtual void replace_many(
const std::vector<unsigned int> & IDs_to_remove,
89 const std::vector<Coord2D> & new_positions,
90 std::vector<unsigned int> & new_IDs);
93 inline void print_tree_depths(std::ostream & outdev)
const {
94 outdev << _trees[0]->max_depth() <<
" "
95 << _trees[1]->max_depth() <<
" "
96 << _trees[2]->max_depth() <<
"\n";
103 void _initialize(
const std::vector<Coord2D> & positions,
104 const Coord2D & left_corner,
const Coord2D & right_corner,
105 const unsigned int max_size);
107 static const unsigned int _nshift = 3;
113 template<
class T>
class triplet {
115 inline const T & operator[](
unsigned int i)
const {
return _contents[i];};
116 inline T & operator[](
unsigned int i) {
return _contents[i];};
118 T _contents[_nshift];
128 void operator+=(
unsigned int shift) {x += shift; y+= shift;};
131 typedef SearchTree<Shuffle> Tree;
132 typedef Tree::circulator circulator;
133 typedef Tree::const_circulator const_circulator;
136 triplet<std::auto_ptr<Tree> > _trees;
137 std::auto_ptr<MinHeap> _heap;
138 std::vector<Point> _points;
139 std::stack<Point *> _available_points;
142 std::vector<Point *> _points_under_review;
145 static const unsigned int _remove_heap_entry = 1;
146 static const unsigned int _review_heap_entry = 2;
147 static const unsigned int _review_neighbour = 4;
152 void _add_label(Point * point,
unsigned int review_flag);
157 void _set_label(Point * point,
unsigned int review_flag);
163 void _deal_with_points_to_review();
166 void _remove_from_search_tree(Point * point_to_remove);
169 void _insert_into_search_tree(Point * new_point);
172 void _point2shuffle(Point & , Shuffle & ,
unsigned int shift);
175 Coord2D _left_corner;
178 int _ID(
const Point *)
const;
180 triplet<unsigned int> _shifts;
181 triplet<unsigned int> _rel_shifts;
183 unsigned int _cp_search_range;
193 class ClosestPair2D::Point {
200 double neighbour_dist2;
202 triplet<circulator> circ;
205 unsigned int review_flag;
208 double distance2(
const Point & other)
const {
209 return coord.distance2(other.coord);
221 if (x>y)
return false;
228 inline int ClosestPair2D::_ID(
const Point * point)
const {
229 return point - &(_points[0]);
234 inline unsigned int ClosestPair2D::size() {
235 return _points.size() - _available_points.size();
240 FASTJET_END_NAMESPACE
242 #endif // __FASTJET_CLOSESTPAIR2D__HH__
bool floor_ln2_less(unsigned x, unsigned y)
returns true if floor(ln_base2(x)) < floor(ln_base2(y)), using Chan's neat trick...
bool operator<(SharedPtr< T > const &t, SharedPtr< U > const &u)
comparison: orgering