37 template <
class KE,
class VTYPE>
39 _pivot(NULL), _leftKD(NULL), _rightKD(NULL), _dims(iDimensions)
42 if (!iElemsList.size())
51 for(; aElemsIt != aElemsItEnd; ++aElemsIt)
53 const KE& aTmp = *aElemsIt;
54 aElemsPtrList.push_back(&aTmp);
67 template <
class KE,
class VTYPE>
69 _pivot(NULL), _leftKD(NULL), _rightKD(NULL), _dims(iDimensions)
82 template <
class KE,
class VTYPE>
97 template <
class KE,
class VTYPE>
101 typename std::vector<const KE*>::const_iterator aPivotIt = choosePivot(iElemsPtrList);
110 VTYPE aPivotDimValue = _pivot->getVectorElem(_splitDim);
111 for(; aElemsIt != aElemsItEnd; ++aElemsIt)
114 if (aElemsIt == aPivotIt)
119 if ((*aElemsIt)->getVectorElem(_splitDim) <= aPivotDimValue)
121 aLeftElems.push_back(*aElemsIt);
125 aRightElems.push_back(*aElemsIt);
133 if (aLeftElems.size())
142 if (aRightElems.size())
162 template <
class KE,
class VTYPE>
171 for(; aElemsIt != aElemsEnd; ++aElemsIt)
173 for (
int aDim = 0; aDim < _dims; ++aDim)
175 VTYPE& aCurValue = (*aElemsIt)->getVectorElem(aDim);
176 if (aCurValue < aMinVals[aDim])
178 aMinVals[aDim] = aCurValue;
180 if (aCurValue > aMaxVals[aDim])
182 aMaxVals[aDim] = aCurValue;
190 for (
int aDim = 0; aDim < _dims; ++aDim)
192 if ( (aMaxVals[aDim] - aMinVals[aDim]) > aLargestRangeValue )
195 aLargestRangeValue = aMaxVals[aDim] - aMinVals[aDim];
200 VTYPE aMedian = aLargestRangeValue / 2 + aMinVals[_splitDim];
203 typename std::vector<const KE*>::const_iterator aClosestElemIt;
205 for(aElemsIt = iElemsPtrList.begin(); aElemsIt != aElemsEnd; ++aElemsIt)
207 VTYPE aCurValue = fabs((*aElemsIt)->getVectorElem(_splitDim) - aMedian);
208 if (aCurValue < aClosestDiff)
210 aClosestDiff = aCurValue;
211 aClosestElemIt = aElemsIt;
215 return aClosestElemIt;
226 template <
class KE,
class VTYPE>
230 for (
int n = 0 ; n < _dims ; ++n)
232 double aDiff = i1->getVectorElem(n) - i2->getVectorElem(n);
233 aDist += aDiff * aDiff;
239 template <
class KE,
class VTYPE>
249 std::list<QueueEntry<KE, VTYPE> > aSearchQueue;
252 recurseNearestNeighboursBBF(iTarget, aHR, aBestMatches, aSearchQueue, iNbSearchSteps);
254 return aBestMatches.
getSet();
257 template <
class KE,
class VTYPE>
262 int& ioRemainingUnqueues)
278 if (!iHR.
split(aLeftHR, aRightHR, _splitDim, _pivot->getVectorElem(_splitDim)))
297 if (iTarget.getVectorElem(_splitDim) > _pivot->getVectorElem(_splitDim))
329 else if (ioRemainingUnqueues > 0 && ioBestMatches.
size() && ioSearchQueue.size())
334 ioRemainingUnqueues--;
337 double aHyperSphereRadius = ioBestMatches.
begin()->_distance;
340 typename std::list<QueueEntry<KE, VTYPE> >::iterator aSQ, aSmallestIt;
342 for (aSQ = ioSearchQueue.begin(); aSQ!= ioSearchQueue.end(); ++aSQ)
344 if (aSQ->_dist < aSmallestDist)
346 aSmallestDist = aSQ->_dist;
351 ioSearchQueue.erase(aSmallestIt);
358 aQueueElem.
_kdTree->recurseNearestNeighboursBBF(iTarget, aQueueElem.
_HR, ioBestMatches, ioSearchQueue, ioRemainingUnqueues);
371 template <
class KE,
class TYPE>
380 template <
class KE,
class TYPE>
382 _leftTop(std::vector<TYPE>(iDim, -std::numeric_limits<TYPE>::
max())),
383 _rightBottom(std::vector<TYPE>(iDim, std::numeric_limits<TYPE>::
max())),
390 template <
class KE,
class TYPE>
392 _leftTop(std::vector<TYPE>(iOther._leftTop)),
393 _rightBottom(std::vector<TYPE>(iOther._rightBottom)),
403 template <
class KE,
class TYPE>
407 if (_leftTop[iSplitDim] >= iSplitVal || _rightBottom[iSplitDim] < iSplitVal)
422 oRight.
_leftTop[iSplitDim] = iSplitVal;
427 template <
class KE,
class TYPE>
430 double aSqDistance = 0;
433 for (
int n = 0 ; n < _dim ; ++n)
435 TYPE aTargetVal = iTarget.getVectorElem(n);
436 TYPE aHRMin = _leftTop[n];
437 TYPE aHRMax = _rightBottom[n];
439 double aDimDist = aTargetVal;
440 if (aTargetVal <= aHRMin)
442 aDimDist = aTargetVal - aHRMin;
444 else if (aTargetVal > aHRMin && aTargetVal < aHRMax)
448 else if (aTargetVal >= aHRMax)
450 aDimDist = aTargetVal - aHRMax;
452 aSqDistance += aDimDist * aDimDist;
458 template <
class KE,
class TYPE>
464 double aDist = calcSqDistance(iTarget);
469 return (aDist < iSqDistance);
472 template <
class KE,
class TYPE>
475 for (
int n = 0 ; n < _dim ; ++n)
480 std::cout <<
"dim[" << n <<
"] = {" << _leftTop[n] <<
" , " << _rightBottom[n] <<
"}" << std::endl;
483 std::cout << std::endl;
486 template <
class KE,
class TYPE>
489 if (iTarget.getVectorSize() != _dim)
491 std::cout <<
"is target in dimension mismatch" << std::endl;
494 for (
int n = 0 ; n < _dim ; ++n)
496 TYPE aDimVal = iTarget.getVectorElem(n);
497 if (aDimVal <= _leftTop[n] || aDimVal >= _rightBottom[n])
506 template <
class KE,
class VTYPE>
509 return (iA._dist < iB._dist);
void insert(const _Key &x)
bool split(HyperRectangle &oLeft, HyperRectangle &oRight, int iSplitDim, TYPE iSplitVal)
std::set< _Key, _Compare > & getSet()
double calcSqDist(const KE *i1, const KE *i2)
bool hasHyperSphereIntersect(const KE &iTarget, double iSqDistance)
std::vector< TYPE > _leftTop
BestMatchSet_t getNearestNeighboursBBF(const KE &iTarget, int iNbBestMatches, int iNbSearchSteps)
double calcSqDistance(const KE &iTarget)
std::vector< KE > ItemVector_t
KDTree< KE, VTYPE > * _kdTree
size_t size() const
Returns the size of the limited_multiset.
std::list< QueueEntry< KE, VTYPE > > QueueEntryList_t
std::vector< const KE * >::const_iterator ItemPtrVectorIt_t
void init(const ItemPtrVector_t &iElemsPtrList)
bool isTargetIn(const KE &iTarget)
void recurseNearestNeighboursBBF(const KE &iTarget, HyperRectangle< KE, VTYPE > &iHR, BestMatchLimitedSet_t &ioBestMatches, QueueEntryList_t &ioSearchQueue, int &ioRemainingUnqueues)
bool operator>(const BestMatch< KE > &iA, const BestMatch< KE > &iB)
HyperRectangle< KE, VTYPE > & _HR
std::vector< const KE * > ItemPtrVector_t
ItemPtrVectorIt_t choosePivot(const ItemPtrVector_t &iElemsPtrList)
std::vector< TYPE > _rightBottom
std::vector< KE >::const_iterator ItemVectorIt_t
KDTree(const ItemVector_t &iElemsList, int iDimensions)