CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
FKDTree< TYPE, numberOfDimensions > Class Template Reference

#include <FKDTree.h>

Public Member Functions

void build (std::vector< FKDPoint< TYPE, numberOfDimensions > > &points)
 
bool empty ()
 
 FKDTree ()
 
void search (const FKDPoint< TYPE, numberOfDimensions > &minPoint, const FKDPoint< TYPE, numberOfDimensions > &maxPoint, std::vector< unsigned int > &foundPoints)
 
std::size_t size () const
 

Private Member Functions

void add_at_position (const FKDPoint< TYPE, numberOfDimensions > &point, const unsigned int position)
 
void add_at_position (FKDPoint< TYPE, numberOfDimensions > &&point, const unsigned int position)
 
bool intersects (unsigned int index, const FKDPoint< TYPE, numberOfDimensions > &minPoint, const FKDPoint< TYPE, numberOfDimensions > &maxPoint, int dimension) const
 
bool is_in_the_box (unsigned int index, const FKDPoint< TYPE, numberOfDimensions > &minPoint, const FKDPoint< TYPE, numberOfDimensions > &maxPoint) const
 
unsigned int leftSonIndex (unsigned int index) const
 
unsigned int partition_complete_kdtree (unsigned int length)
 
unsigned int rightSonIndex (unsigned int index) const
 

Private Attributes

unsigned int theDepth
 
std::array< std::vector< TYPE >, numberOfDimensions > theDimensions
 
std::vector< unsigned int > theIds
 
std::vector< unsigned int > theIntervalLength
 
std::vector< unsigned int > theIntervalMin
 
unsigned int theNumberOfPoints
 

Detailed Description

template<class TYPE, unsigned int numberOfDimensions>
class FKDTree< TYPE, numberOfDimensions >

Definition at line 38 of file FKDTree.h.

Constructor & Destructor Documentation

template<class TYPE , unsigned int numberOfDimensions>
FKDTree< TYPE, numberOfDimensions >::FKDTree ( )
inline

Definition at line 43 of file FKDTree.h.

References FKDTree< TYPE, numberOfDimensions >::theDepth, and FKDTree< TYPE, numberOfDimensions >::theNumberOfPoints.

44  {
46  theDepth = 0;
47  }
unsigned int theDepth
Definition: FKDTree.h:290
unsigned int theNumberOfPoints
Definition: FKDTree.h:289

Member Function Documentation

template<class TYPE , unsigned int numberOfDimensions>
void FKDTree< TYPE, numberOfDimensions >::add_at_position ( const FKDPoint< TYPE, numberOfDimensions > &  point,
const unsigned int  position 
)
inlineprivate

Definition at line 273 of file FKDTree.h.

References FKDPoint< TYPE, numberOfDimensions >::getId(), mps_fire::i, position, FKDTree< TYPE, numberOfDimensions >::theDimensions, and FKDTree< TYPE, numberOfDimensions >::theIds.

Referenced by FKDTree< TYPE, numberOfDimensions >::build().

275  {
276  for (unsigned int i = 0; i < numberOfDimensions; ++i)
277  theDimensions[i][position] = point[i];
278  theIds[position] = point.getId();
279  }
std::array< std::vector< TYPE >, numberOfDimensions > theDimensions
Definition: FKDTree.h:293
unsigned int getId() const
Definition: FKDPoint.h:67
std::vector< unsigned int > theIds
Definition: FKDTree.h:296
static int position[264][3]
Definition: ReadPGInfo.cc:509
template<class TYPE , unsigned int numberOfDimensions>
void FKDTree< TYPE, numberOfDimensions >::add_at_position ( FKDPoint< TYPE, numberOfDimensions > &&  point,
const unsigned int  position 
)
inlineprivate

Definition at line 281 of file FKDTree.h.

References mps_fire::i, point, position, FKDTree< TYPE, numberOfDimensions >::theDimensions, and FKDTree< TYPE, numberOfDimensions >::theIds.

283  {
284  for (unsigned int i = 0; i < numberOfDimensions; ++i)
285  theDimensions[i][position] = point[i];
286  theIds[position] = point.getId();
287  }
std::array< std::vector< TYPE >, numberOfDimensions > theDimensions
Definition: FKDTree.h:293
unsigned int getId() const
Definition: FKDPoint.h:67
std::vector< unsigned int > theIds
Definition: FKDTree.h:296
static int position[264][3]
Definition: ReadPGInfo.cc:509
template<class TYPE , unsigned int numberOfDimensions>
void FKDTree< TYPE, numberOfDimensions >::build ( std::vector< FKDPoint< TYPE, numberOfDimensions > > &  points)
inline

Definition at line 133 of file FKDTree.h.

References a, FKDTree< TYPE, numberOfDimensions >::add_at_position(), b, particleFlowClusterECALTimeSelected_cfi::depth, pat::helper::ParametrizationHelper::dimension(), mps_fire::i, CMSBoostedTauSeedingParameters_cfi::maxDepth, FKDTree< TYPE, numberOfDimensions >::partition_complete_kdtree(), hiPixelPairStep_cff::points, FKDTree< TYPE, numberOfDimensions >::theDepth, FKDTree< TYPE, numberOfDimensions >::theDimensions, FKDTree< TYPE, numberOfDimensions >::theIds, FKDTree< TYPE, numberOfDimensions >::theIntervalLength, FKDTree< TYPE, numberOfDimensions >::theIntervalMin, and FKDTree< TYPE, numberOfDimensions >::theNumberOfPoints.

Referenced by psClasses.BuildThread::run().

134  {
135  // initialization of the data members
136  theNumberOfPoints = points.size();
137  theDepth = ilog2(theNumberOfPoints);
140  for (unsigned int i = 0; i < numberOfDimensions; ++i)
142  theIds.resize(theNumberOfPoints);
143 
144  // building is done by reordering elements in a partition starting at theIntervalMin
145  // for a number of elements theIntervalLength
146  unsigned int dimension;
147  theIntervalMin[0] = 0;
149 
150  // building for each level starts here
151  for (unsigned int depth = 0; depth < theDepth; ++depth)
152  {
153  // A heapified left-balanced tree can be represented in memory as an array.
154  // Each level contains a power of two number of elements and starts from element 2^depth -1
155  dimension = depth % numberOfDimensions;
156  unsigned int firstIndexInDepth = (1 << depth) - 1;
157  unsigned int maxDepth = (1 << depth);
158  for (unsigned int indexInDepth = 0; indexInDepth < maxDepth; ++indexInDepth)
159  {
160  unsigned int indexInArray = firstIndexInDepth + indexInDepth;
161  unsigned int leftSonIndexInArray = 2 * indexInArray + 1;
162  unsigned int rightSonIndexInArray = leftSonIndexInArray + 1;
163 
164  // partitioning is done by choosing the pivotal element that keeps the tree heapified
165  // and left-balanced
166  unsigned int whichElementInInterval = partition_complete_kdtree(
167  theIntervalLength[indexInArray]);
168  // the elements have been partitioned in two unsorted subspaces (one containing the elements
169  // smaller than the pivot, the other containing those greater than the pivot)
170  std::nth_element(points.begin() + theIntervalMin[indexInArray],
171  points.begin() + theIntervalMin[indexInArray] + whichElementInInterval,
172  points.begin() + theIntervalMin[indexInArray]
173  + theIntervalLength[indexInArray],
175  const FKDPoint<TYPE,numberOfDimensions> & b) -> bool
176  {
177  if(a[dimension] == b[dimension])
178  return a.getId() < b.getId();
179  else
180  return a[dimension] < b[dimension];
181  });
182  // the element is placed in its final position in the internal array representation
183  // of the tree
184  add_at_position(points[theIntervalMin[indexInArray] + whichElementInInterval],
185  indexInArray);
186  if (leftSonIndexInArray < theNumberOfPoints)
187  {
188  theIntervalMin[leftSonIndexInArray] = theIntervalMin[indexInArray];
189  theIntervalLength[leftSonIndexInArray] = whichElementInInterval;
190  }
191 
192  if (rightSonIndexInArray < theNumberOfPoints)
193  {
194  theIntervalMin[rightSonIndexInArray] = theIntervalMin[indexInArray]
195  + whichElementInInterval + 1;
196  theIntervalLength[rightSonIndexInArray] = (theIntervalLength[indexInArray]
197  - 1 - whichElementInInterval);
198  }
199  }
200  }
201  // the last level of the tree may not be complete and needs special treatment
202  dimension = theDepth % numberOfDimensions;
203  unsigned int firstIndexInDepth = (1 << theDepth) - 1;
204  for (unsigned int indexInArray = firstIndexInDepth; indexInArray < theNumberOfPoints;
205  ++indexInArray)
206  {
207  add_at_position(points[theIntervalMin[indexInArray]], indexInArray);
208  }
209 
210  }
std::array< std::vector< TYPE >, numberOfDimensions > theDimensions
Definition: FKDTree.h:293
unsigned int theDepth
Definition: FKDTree.h:290
std::vector< unsigned int > theIds
Definition: FKDTree.h:296
std::vector< unsigned int > theIntervalMin
Definition: FKDTree.h:295
unsigned int partition_complete_kdtree(unsigned int length)
Definition: FKDTree.h:228
unsigned int theNumberOfPoints
Definition: FKDTree.h:289
void add_at_position(const FKDPoint< TYPE, numberOfDimensions > &point, const unsigned int position)
Definition: FKDTree.h:273
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
std::vector< unsigned int > theIntervalLength
Definition: FKDTree.h:294
uint32_t dimension(pat::CandKinResolution::Parametrization parametrization)
Returns the number of free parameters in a parametrization (3 or 4)
template<class TYPE , unsigned int numberOfDimensions>
bool FKDTree< TYPE, numberOfDimensions >::empty ( )
inline
template<class TYPE , unsigned int numberOfDimensions>
bool FKDTree< TYPE, numberOfDimensions >::intersects ( unsigned int  index,
const FKDPoint< TYPE, numberOfDimensions > &  minPoint,
const FKDPoint< TYPE, numberOfDimensions > &  maxPoint,
int  dimension 
) const
inlineprivate

Definition at line 252 of file FKDTree.h.

References FKDTree< TYPE, numberOfDimensions >::theDimensions.

Referenced by FKDTree< TYPE, numberOfDimensions >::search().

254  {
255  return (theDimensions[dimension][index] <= maxPoint[dimension]
256  && theDimensions[dimension][index] >= minPoint[dimension]);
257  }
std::array< std::vector< TYPE >, numberOfDimensions > theDimensions
Definition: FKDTree.h:293
uint32_t dimension(pat::CandKinResolution::Parametrization parametrization)
Returns the number of free parameters in a parametrization (3 or 4)
template<class TYPE , unsigned int numberOfDimensions>
bool FKDTree< TYPE, numberOfDimensions >::is_in_the_box ( unsigned int  index,
const FKDPoint< TYPE, numberOfDimensions > &  minPoint,
const FKDPoint< TYPE, numberOfDimensions > &  maxPoint 
) const
inlineprivate

Definition at line 260 of file FKDTree.h.

References mps_fire::i, and FKDTree< TYPE, numberOfDimensions >::theDimensions.

Referenced by FKDTree< TYPE, numberOfDimensions >::search().

262  {
263  for (unsigned int i = 0; i < numberOfDimensions; ++i)
264  {
265  if ((theDimensions[i][index] <= maxPoint[i]
266  && theDimensions[i][index] >= minPoint[i]) == false)
267  return false;
268  }
269  return true;
270  }
std::array< std::vector< TYPE >, numberOfDimensions > theDimensions
Definition: FKDTree.h:293
template<class TYPE , unsigned int numberOfDimensions>
unsigned int FKDTree< TYPE, numberOfDimensions >::leftSonIndex ( unsigned int  index) const
inlineprivate

Definition at line 241 of file FKDTree.h.

Referenced by FKDTree< TYPE, numberOfDimensions >::search().

242  {
243  return 2 * index + 1;
244  }
template<class TYPE , unsigned int numberOfDimensions>
unsigned int FKDTree< TYPE, numberOfDimensions >::partition_complete_kdtree ( unsigned int  length)
inlineprivate

Definition at line 228 of file FKDTree.h.

References diffTreeTool::index.

Referenced by FKDTree< TYPE, numberOfDimensions >::build().

229  {
230  if (length == 1)
231  return 0;
232  unsigned int index = 1 << (ilog2(length));
233 
234  if ((index / 2) - 1 <= length - index)
235  return index - 1;
236  else
237  return length - index / 2;
238  }
template<class TYPE , unsigned int numberOfDimensions>
unsigned int FKDTree< TYPE, numberOfDimensions >::rightSonIndex ( unsigned int  index) const
inlineprivate

Definition at line 246 of file FKDTree.h.

247  {
248  return 2 * index + 2;
249  }
template<class TYPE , unsigned int numberOfDimensions>
void FKDTree< TYPE, numberOfDimensions >::search ( const FKDPoint< TYPE, numberOfDimensions > &  minPoint,
const FKDPoint< TYPE, numberOfDimensions > &  maxPoint,
std::vector< unsigned int > &  foundPoints 
)
inline

Definition at line 60 of file FKDTree.h.

References particleFlowClusterECALTimeSelected_cfi::depth, pat::helper::ParametrizationHelper::dimension(), diffTreeTool::index, reco::helper::VirtualJetProducerHelper::intersection(), FKDTree< TYPE, numberOfDimensions >::intersects(), FKDTree< TYPE, numberOfDimensions >::is_in_the_box(), FKDTree< TYPE, numberOfDimensions >::leftSonIndex(), min(), FQueue< T >::pop_front(), FQueue< T >::push_back(), FQueue< T >::size(), FKDTree< TYPE, numberOfDimensions >::theDepth, FKDTree< TYPE, numberOfDimensions >::theDimensions, FKDTree< TYPE, numberOfDimensions >::theIds, and FKDTree< TYPE, numberOfDimensions >::theNumberOfPoints.

Referenced by BeautifulSoup.SoupStrainer::search().

63  {
64  //going down the FKDTree, one needs track which indices have to be visited in the following level.
65  //a custom queue is created, since std::queue is based on lists which are sometimes not performing
66  // well on computing accelerators
67  // The initial size of the queue has to be a power of two for allowing fast modulo % operation.
68  FQueue<unsigned int> indicesToVisit(16);
69 
70  //The root element is pushed first
71  indicesToVisit.push_back(0);
72  unsigned int index;
73  bool intersection;
74  unsigned int dimension;
75  unsigned int numberOfindicesToVisitThisDepth;
76  unsigned int numberOfSonsToVisitNext;
77  unsigned int firstSonToVisitNext;
78 
79  //The loop over levels of the FKDTree starts here
80  for (unsigned int depth = 0; depth < theDepth + 1; ++depth)
81  {
82  // At each level, comparisons are performed for a different dimension in round robin.
83  dimension = depth % numberOfDimensions;
84  numberOfindicesToVisitThisDepth = indicesToVisit.size();
85  // Loop over the nodes to be visit at this level
86  for (unsigned int visitedindicesThisDepth = 0;
87  visitedindicesThisDepth < numberOfindicesToVisitThisDepth;
88  visitedindicesThisDepth++)
89  {
90 
91  index = indicesToVisit[visitedindicesThisDepth];
92  // check if the element's dimension lays between the two box borders
93  intersection = intersects(index, minPoint, maxPoint, dimension);
94  firstSonToVisitNext = leftSonIndex(index);
95 
96 
97  if (intersection)
98  {
99  // Check if the element is contained in the box and push it to the result
100  if (is_in_the_box(index, minPoint, maxPoint))
101  {
102  foundPoints.emplace_back(theIds[index]);
103  }
104  //if the element is between the box borders, both the its sons have to be visited
105  numberOfSonsToVisitNext = (firstSonToVisitNext < theNumberOfPoints)
106  + ((firstSonToVisitNext + 1) < theNumberOfPoints);
107  }
108  else
109  {
110  // depending on the position of the element wrt the box, one son will be visited (if it exists)
111  firstSonToVisitNext += (theDimensions[dimension][index]
112  < minPoint[dimension]);
113 
114  numberOfSonsToVisitNext = std::min(
115  (firstSonToVisitNext < theNumberOfPoints)
116  + ((firstSonToVisitNext + 1) < theNumberOfPoints), 1);
117  }
118 
119  // the indices of the sons to be visited in the next iteration are pushed in the queue
120  for (unsigned int whichSon = 0; whichSon < numberOfSonsToVisitNext; ++whichSon)
121  {
122  indicesToVisit.push_back(firstSonToVisitNext + whichSon);
123  }
124  }
125  // a new element is popped from the queue
126  indicesToVisit.pop_front(numberOfindicesToVisitThisDepth);
127  }
128 
129  }
std::array< std::vector< TYPE >, numberOfDimensions > theDimensions
Definition: FKDTree.h:293
bool intersects(unsigned int index, const FKDPoint< TYPE, numberOfDimensions > &minPoint, const FKDPoint< TYPE, numberOfDimensions > &maxPoint, int dimension) const
Definition: FKDTree.h:252
unsigned int theDepth
Definition: FKDTree.h:290
std::vector< unsigned int > theIds
Definition: FKDTree.h:296
Definition: FQueue.h:7
T min(T a, T b)
Definition: MathUtil.h:58
bool is_in_the_box(unsigned int index, const FKDPoint< TYPE, numberOfDimensions > &minPoint, const FKDPoint< TYPE, numberOfDimensions > &maxPoint) const
Definition: FKDTree.h:260
unsigned int theNumberOfPoints
Definition: FKDTree.h:289
unsigned int leftSonIndex(unsigned int index) const
Definition: FKDTree.h:241
uint32_t dimension(pat::CandKinResolution::Parametrization parametrization)
Returns the number of free parameters in a parametrization (3 or 4)
template<class TYPE , unsigned int numberOfDimensions>
std::size_t FKDTree< TYPE, numberOfDimensions >::size ( void  ) const
inline

Definition at line 212 of file FKDTree.h.

References FKDTree< TYPE, numberOfDimensions >::theNumberOfPoints.

Referenced by ntupleDataFormat._Collection::__iter__(), and ntupleDataFormat._Collection::__len__().

213  {
214  return theNumberOfPoints;
215  }
unsigned int theNumberOfPoints
Definition: FKDTree.h:289

Member Data Documentation

template<class TYPE , unsigned int numberOfDimensions>
unsigned int FKDTree< TYPE, numberOfDimensions >::theDepth
private
template<class TYPE , unsigned int numberOfDimensions>
std::array<std::vector<TYPE>, numberOfDimensions> FKDTree< TYPE, numberOfDimensions >::theDimensions
private
template<class TYPE , unsigned int numberOfDimensions>
std::vector<unsigned int> FKDTree< TYPE, numberOfDimensions >::theIds
private
template<class TYPE , unsigned int numberOfDimensions>
std::vector<unsigned int> FKDTree< TYPE, numberOfDimensions >::theIntervalLength
private

Definition at line 294 of file FKDTree.h.

Referenced by FKDTree< TYPE, numberOfDimensions >::build().

template<class TYPE , unsigned int numberOfDimensions>
std::vector<unsigned int> FKDTree< TYPE, numberOfDimensions >::theIntervalMin
private

Definition at line 295 of file FKDTree.h.

Referenced by FKDTree< TYPE, numberOfDimensions >::build().

template<class TYPE , unsigned int numberOfDimensions>
unsigned int FKDTree< TYPE, numberOfDimensions >::theNumberOfPoints
private