63                 for (T i = 0; i < 64; ++i)
 
   76         template<
typename T, 
typename CloudType>
 
   81                 for (
int i = 0; i < v.size(); ++i)
 
   93         template<
typename T, 
typename Heap, 
typename CloudType>
 
   96                 T minVal(std::numeric_limits<T>::max());
 
   97                 T maxVal(std::numeric_limits<T>::lowest());
 
  101                         const T val(cloud.coeff(dim, *it));
 
  102                         minVal = 
min(val, minVal);
 
  103                         maxVal = max(val, maxVal);
 
  106                 return make_pair(minVal, maxVal);
 
  109         template<
typename T, 
typename Heap, 
typename CloudType>
 
  112                 const int count(last - first);
 
  114                 const unsigned pos(nodes.size());
 
  117                 if (count <= 
int(bucketSize))
 
  119                         const uint32_t initBucketsSize(buckets.size());
 
  121                         for (
int i = 0; i < count; ++i)
 
  123                                 const Index index(*(first+i));
 
  124                                 assert(index < cloud.cols());
 
  125                                 buckets.push_back(
BucketEntry(&cloud.coeff(0, index), index));
 
  129                         nodes.push_back(
Node(createDimChildBucketSize(dim, count),initBucketsSize));
 
  134                 const unsigned cutDim = argMax<T, CloudType>(maxValues - minValues);
 
  135                 const T idealCutVal((maxValues(cutDim) + minValues(cutDim))/2);
 
  138                 const pair<T,T> minMaxVals(getBounds(first, last, cutDim));
 
  142                 if (idealCutVal < minMaxVals.first)
 
  143                         cutVal = minMaxVals.first;
 
  144                 else if (idealCutVal > minMaxVals.second)
 
  145                         cutVal = minMaxVals.second;
 
  147                         cutVal = idealCutVal;
 
  154                         while (l < count && cloud.coeff(cutDim, *(first+l)) < cutVal)
 
  156                         while (r >= 0 && cloud.coeff(cutDim, *(first+r)) >= cutVal)
 
  160                         swap(*(first+l), *(first+r));
 
  168                         while (l < count && cloud.coeff(cutDim, *(first+l)) <= cutVal)
 
  170                         while (r >= br1 && cloud.coeff(cutDim, *(first+r)) > cutVal)
 
  174                         swap(*(first+l), *(first+r));
 
  181                 if (idealCutVal < minMaxVals.first)
 
  183                 else if (idealCutVal > minMaxVals.second)
 
  185                 else if (br1 > count / 2)
 
  187                 else if (br2 < count / 2)
 
  190                         leftCount = count / 2;
 
  191                 assert(leftCount > 0);
 
  205                 assert(leftCount < count);
 
  208                 Vector leftMaxValues(maxValues);
 
  209                 leftMaxValues[cutDim] = cutVal;
 
  211                 Vector rightMinValues(minValues);
 
  212                 rightMinValues[cutDim] = cutVal;
 
  215                 nodes.push_back(
Node(0, cutVal));
 
  218                 const unsigned _UNUSED leftChild = buildNodes(first, first + leftCount, minValues, leftMaxValues);
 
  219                 assert(leftChild == pos + 1);
 
  220                 const unsigned rightChild = buildNodes(first + leftCount, last, rightMinValues, maxValues);
 
  223                 nodes[pos].dimChildBucketSize = createDimChildBucketSize(cutDim, rightChild);
 
  227         template<
typename T, 
typename Heap, 
typename CloudType>
 
  230                 bucketSize(additionalParameters.
get<unsigned>(
"bucketSize", 8)),
 
  232                 dimMask((1<<dimBitCount)-1)
 
  239                         for (
int i = 0; i < 
cloud.cols(); ++i)
 
  245                 const uint64_t maxNodeCount((0x1ULL << (32-
dimBitCount)) - 1);
 
  247                 if (estimatedNodeCount > maxNodeCount)
 
  249                         throw runtime_error(
"Cloud has a risk to have more nodes (" + std::to_string(estimatedNodeCount) + 
") than the kd-tree allows (" + std::to_string(maxNodeCount) + 
"). " 
  250                                         "The kd-tree has " + std::to_string(
dimBitCount) + 
" bits for dimensions and " + std::to_string((32-
dimBitCount)) + 
" bits for node indices");
 
  255                 buildPoints.reserve(
cloud.cols());
 
  256                 for (
int i = 0; i < 
cloud.cols(); ++i)
 
  259                         buildPoints.push_back(i);
 
  274         template<
typename T, 
typename Heap, 
typename CloudType>
 
  277                 checkSizesKnn(query, indices, dists2, k, optionFlags);
 
  282                 const T maxRadius2(maxRadius * maxRadius);
 
  284                 const int colCount(query.cols());
 
  286                 assert(nodes.size() > 0);
 
  289                 unsigned long leafTouchedCount(0);
 
  295                 std::vector<T> off(dim, 0);
 
  297 #pragma omp for reduction(+:leafTouchedCount) schedule(guided,32) 
  298                 for (
int i = 0; i < colCount; ++i)
 
  300                         leafTouchedCount += onePointKnn(query, indices, dists2, i, heap, off, maxError2, maxRadius2, allowSelfMatch, collectStatistics, sortResults);
 
  303                 return leafTouchedCount;
 
  306         template<
typename T, 
typename Heap, 
typename CloudType>
 
  309                 checkSizesKnn(query, indices, dists2, k, optionFlags, &maxRadii);
 
  315                 const int colCount(query.cols());
 
  317                 assert(nodes.size() > 0);
 
  319                 unsigned long leafTouchedCount(0);
 
  325                 std::vector<T> off(dim, 0);
 
  327 #pragma omp for reduction(+:leafTouchedCount) schedule(guided,32) 
  328                 for (
int i = 0; i < colCount; ++i)
 
  330                         const T maxRadius(maxRadii[i]);
 
  331                         const T maxRadius2(maxRadius * maxRadius);
 
  332                         leafTouchedCount += onePointKnn(query, indices, dists2, i, heap, off, maxError2, maxRadius2, allowSelfMatch, collectStatistics, sortResults);
 
  335                 return leafTouchedCount;
 
  338         template<
typename T, 
typename Heap, 
typename CloudType>
 
  339         unsigned long KDTreeUnbalancedPtInLeavesImplicitBoundsStackOpt<T, Heap, CloudType>::onePointKnn(
const Matrix& query, 
IndexMatrix& indices, 
Matrix& dists2, 
int i, Heap& heap, std::vector<T>& off, 
const T maxError2, 
const T maxRadius2, 
const bool allowSelfMatch, 
const bool collectStatistics, 
const bool sortResults)
 const 
  341                 fill(off.begin(), off.end(), 
static_cast<T
>(0));
 
  343                 unsigned long leafTouchedCount(0);
 
  347                         if (collectStatistics)
 
  348                                 leafTouchedCount += recurseKnn<true, true>(&query.coeff(0, i), 0, 0, heap, off, maxError2, maxRadius2);
 
  350                                 recurseKnn<true, false>(&query.coeff(0, i), 0, 0, heap, off, maxError2, maxRadius2);
 
  354                         if (collectStatistics)
 
  355                                 leafTouchedCount += recurseKnn<false, true>(&query.coeff(0, i), 0, 0, heap, off, maxError2, maxRadius2);
 
  357                                 recurseKnn<false, false>(&query.coeff(0, i), 0, 0, heap, off, maxError2, maxRadius2);
 
  363                 heap.getData(indices.col(i), dists2.col(i));
 
  364                 return leafTouchedCount;
 
  367         template<
typename T, 
typename Heap, 
typename CloudType> 
template<
bool allowSelfMatch, 
bool collectStatistics>
 
  370                 const Node& node(nodes[n]);
 
  373                 if (cd == uint32_t(dim))
 
  378                         for (uint32_t i = 0; i < bucketSize; ++i)
 
  384                                 const T* qPtr(query);
 
  385                                 const T* dPtr(bucket->
pt);
 
  386                                 for (
int i = 0; i < this->dim; ++i)
 
  388                                         const T diff(*qPtr - *dPtr);
 
  392                                 if ((dist <= maxRadius2) &&
 
  393                                         (dist < heap.headValue()) &&
 
  394                                         (allowSelfMatch || (dist > numeric_limits<T>::epsilon()))
 
  396                                         heap.replaceHead(bucket->
index, dist);
 
  399                         return (
unsigned long)(bucketSize);
 
  404                         unsigned long leafVisitedCount(0);
 
  407                         const T old_off(offcd);
 
  408                         const T new_off(query[cd] - node.
cutVal);
 
  411                                 if (collectStatistics)
 
  412                                         leafVisitedCount += recurseKnn<allowSelfMatch, true>(query, rightChild, rd, heap, off, maxError2, maxRadius2);
 
  414                                         recurseKnn<allowSelfMatch, false>(query, rightChild, rd, heap, off, maxError2, maxRadius2);
 
  415                                 rd += - old_off*old_off + new_off*new_off;
 
  416                                 if ((rd <= maxRadius2) &&
 
  417                                         (rd * maxError2 < heap.headValue()))
 
  420                                         if (collectStatistics)
 
  421                                                 leafVisitedCount += recurseKnn<allowSelfMatch, true>(query, n + 1, rd, heap, off, maxError2, maxRadius2);
 
  423                                                 recurseKnn<allowSelfMatch, false>(query, n + 1, rd, heap, off, maxError2, maxRadius2);
 
  429                                 if (collectStatistics)
 
  430                                         leafVisitedCount += recurseKnn<allowSelfMatch, true>(query, n+1, rd, heap, off, maxError2, maxRadius2);
 
  432                                         recurseKnn<allowSelfMatch, false>(query, n+1, rd, heap, off, maxError2, maxRadius2);
 
  433                                 rd += - old_off*old_off + new_off*new_off;
 
  434                                 if ((rd <= maxRadius2) &&
 
  435                                         (rd * maxError2 < heap.headValue()))
 
  438                                         if (collectStatistics)
 
  439                                                 leafVisitedCount += recurseKnn<allowSelfMatch, true>(query, rightChild, rd, heap, off, maxError2, maxRadius2);
 
  441                                                 recurseKnn<allowSelfMatch, false>(query, rightChild, rd, heap, off, maxError2, maxRadius2);
 
  445                         return leafVisitedCount;