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" 40 #include "fastjet/SharedPtr.hh" 42 FASTJET_BEGIN_NAMESPACE
51 class ClosestPair2D :
public ClosestPair2DBase {
57 ClosestPair2D(
const std::vector<Coord2D> & positions,
58 const Coord2D & left_corner,
const Coord2D & right_corner) {
59 _initialize(positions, left_corner, right_corner, positions.size());
64 ClosestPair2D(
const std::vector<Coord2D> & positions,
65 const Coord2D & left_corner,
const Coord2D & right_corner,
66 const unsigned int max_size) {
67 _initialize(positions, left_corner, right_corner, max_size);
72 void closest_pair(
unsigned int & ID1,
unsigned int & ID2,
73 double & distance2)
const;
76 void remove(
unsigned int ID);
80 unsigned int insert(
const Coord2D &);
84 virtual unsigned int replace(
unsigned int ID1,
unsigned int ID2,
85 const Coord2D & position);
89 virtual void replace_many(
const std::vector<unsigned int> & IDs_to_remove,
90 const std::vector<Coord2D> & new_positions,
91 std::vector<unsigned int> & new_IDs);
94 inline void print_tree_depths(std::ostream & outdev)
const {
95 outdev << _trees[0]->max_depth() <<
" " 96 << _trees[1]->max_depth() <<
" " 97 << _trees[2]->max_depth() <<
"\n";
104 void _initialize(
const std::vector<Coord2D> & positions,
105 const Coord2D & left_corner,
const Coord2D & right_corner,
106 const unsigned int max_size);
108 static const unsigned int _nshift = 3;
114 template<
class T>
class triplet {
116 inline const T & operator[](
unsigned int i)
const {
return _contents[i];};
117 inline T & operator[](
unsigned int i) {
return _contents[i];};
119 T _contents[_nshift];
129 void operator+=(
unsigned int shift) {x += shift; y+= shift;};
132 typedef SearchTree<Shuffle> Tree;
133 typedef Tree::circulator circulator;
134 typedef Tree::const_circulator const_circulator;
137 triplet<SharedPtr<Tree> > _trees;
138 SharedPtr<MinHeap> _heap;
139 std::vector<Point> _points;
140 std::stack<Point *> _available_points;
143 std::vector<Point *> _points_under_review;
146 static const unsigned int _remove_heap_entry = 1;
147 static const unsigned int _review_heap_entry = 2;
148 static const unsigned int _review_neighbour = 4;
153 void _add_label(Point * point,
unsigned int review_flag);
158 void _set_label(Point * point,
unsigned int review_flag);
164 void _deal_with_points_to_review();
167 void _remove_from_search_tree(Point * point_to_remove);
170 void _insert_into_search_tree(Point * new_point);
173 void _point2shuffle(Point & , Shuffle & ,
unsigned int shift);
176 Coord2D _left_corner;
179 int _ID(
const Point *)
const;
181 triplet<unsigned int> _shifts;
182 triplet<unsigned int> _rel_shifts;
184 unsigned int _cp_search_range;
194 class ClosestPair2D::Point {
201 double neighbour_dist2;
203 triplet<circulator> circ;
206 unsigned int review_flag;
209 double distance2(
const Point & other)
const {
210 return coord.distance2(other.coord);
222 if (x>y)
return false;
229 inline int ClosestPair2D::_ID(
const Point * point)
const {
230 return point - &(_points[0]);
235 inline unsigned int ClosestPair2D::size() {
236 return _points.size() - _available_points.size();
241 FASTJET_END_NAMESPACE
243 #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