33 #include "../nabo/index_heap.h" 
   44         template<
typename T, 
typename CloudType>
 
   49                 for (
int i = 0; i < v.size(); ++i)
 
   60         template<
typename T, 
typename CloudType>
 
   68                         if (elCount & (1 << i))
 
   71                 for (
int j = 0; j <= i; ++j)
 
   77         template<
typename T, 
typename CloudType>
 
   81                 for (
int i = 0; i < indexes.size(); ++i)
 
   82                         cloudIndexes.coeffRef(i) = nodes[indexes[i]].index;
 
   86         template<
typename T, 
typename CloudType>
 
   89                 const size_t count(last - first);
 
   93                         nodes[pos] = 
Node(first->pos, -1, first->index);
 
   99                 Vector mean(Vector::Zero(this->dim));
 
  102                 mean /= last - first;
 
  104                 Vector var(Vector::Zero(this->dim));
 
  106                         var += (it->pos - mean).cwise() * (it->pos - mean);
 
  108                 const size_t cutDim = argMax<T>(var);
 
  114                 const size_t recurseCount(count-1);
 
  115                 const size_t rightCount(recurseCount/2);
 
  116                 const size_t leftCount(recurseCount-rightCount);
 
  117                 assert(last - rightCount == first + leftCount + 1);
 
  119                 nodes[pos] = 
Node((first+leftCount)->pos, cutDim, (first+leftCount)->index);
 
  126                         buildNodes(first, first + leftCount, childLeft(pos));
 
  127                         buildNodes(first + leftCount + 1, last, childRight(pos));
 
  131                         nodes[childLeft(pos)] = 
Node(first->pos, -1, first->index);
 
  132                         nodes[childRight(pos)] = 
Node(
Vector(), -2, 0);
 
  136         template<
typename T, 
typename CloudType>
 
  139                 const Node& node(nodes[pos]);
 
  144                                 cout << 
"<circle cx=\"" << 100*node.
pos(0) << 
"\" cy=\"" << 100*node.
pos(1) << 
"\" r=\"1\" stroke=\"black\" stroke-width=\"0.2\" fill=\"red\"/>" << endl;
 
  146                                 cout << 
"pt at\n" << node.
pos << endl;
 
  153                         Vector leftMaxValues(maxValues);
 
  154                         leftMaxValues[node.
dim] = node.
pos[node.
dim];
 
  156                         Vector rightMinValues(minValues);
 
  157                         rightMinValues[node.
dim] = node.
pos[node.
dim];
 
  161                                 cout << 
"<line x1=\"" << 100*rightMinValues(0) << 
"\" y1=\"" << 100*rightMinValues(1) << 
"\" x2=\"" << 100*leftMaxValues(0) << 
"\" y2=\"" << 100*leftMaxValues(1) << 
"\" style=\"stroke:rgb(0,0,0);stroke-width:0.2\"/>" << endl;
 
  163                                 cout << 
"cut from\n" << rightMinValues << 
"\nto\n" << leftMaxValues << endl;
 
  165                         dump(minValues, leftMaxValues, childLeft(pos));
 
  166                         dump(rightMinValues, maxValues, childRight(pos));
 
  170         template<
typename T, 
typename CloudType>
 
  176                 buildPoints.reserve(
cloud.cols());
 
  177                 for (
int i = 0; i < 
cloud.cols(); ++i)
 
  187                 buildNodes(buildPoints.begin(), buildPoints.end(), 0);
 
  195         template<
typename T, 
typename CloudType>
 
  201         template<
typename T, 
typename CloudType>
 
  204                 typedef priority_queue<SearchElement> Queue;
 
  212                 statistics.lastQueryVisitCount = 0;
 
  214                 while (!queue.empty())
 
  226                                 const Node& node(nodes[n]);
 
  227                                 assert (node.
dim != -2);
 
  230                                 const T dist(dist2<T>(node.
pos, query));
 
  232                                         (allowSelfMatch || (dist > numeric_limits<T>::epsilon())))
 
  239                                 const T offset(query.coeff(node.
dim) - node.
pos.coeff(node.
dim));
 
  240                                 const T offset2(offset * offset);
 
  245                                         if (offset2 < bestDist && nodes[childLeft(n)].dim != -2)
 
  248                                         if (nodes[childRight(n)].dim != -2)
 
  256                                         if (offset2 < bestDist && nodes[childRight(n)].dim != -2)
 
  259                                         if (nodes[childLeft(n)].dim != -2)
 
  264                                 ++statistics.lastQueryVisitCount;
 
  267                 statistics.totalVisitCount += statistics.lastQueryVisitCount;
 
  272                 return cloudIndexesFromNodesIndexes(heap.getIndexes());
 
  284         template<
typename T, 
typename CloudType>
 
  290         template<
typename T, 
typename CloudType>
 
  295                 assert(nodes.size() > 0);
 
  296                 assert(nodes[0].pos.size() == query.size());
 
  298                 Vector off(Vector::Zero(nodes[0].pos.size()));
 
  300                 statistics.lastQueryVisitCount = 0;
 
  302                 recurseKnn(query, 0, 0, heap, off, 1 + 
epsilon, allowSelfMatch);
 
  307                 statistics.totalVisitCount += statistics.lastQueryVisitCount;
 
  309                 return cloudIndexesFromNodesIndexes(heap.getIndexes());
 
  312         template<
typename T, 
typename CloudType>
 
  315                 const Node& node(nodes[n]);
 
  316                 const int cd(node.
dim);
 
  318                 ++statistics.lastQueryVisitCount;
 
  323                 const T dist(dist2<T, CloudType>(node.
pos, query));
 
  325                         (allowSelfMatch || (dist > numeric_limits<T>::epsilon()))
 
  331                         const T old_off(off.coeff(cd));
 
  332                         const T new_off(query.coeff(cd) - node.
pos.coeff(cd));
 
  335                                 recurseKnn(query, childRight(n), rd, heap, off, maxError, allowSelfMatch);
 
  336                                 rd += - old_off*old_off + new_off*new_off;
 
  339                                         off.coeffRef(cd) = new_off;
 
  340                                         recurseKnn(query, childLeft(n), rd, heap, off, maxError, allowSelfMatch);
 
  341                                         off.coeffRef(cd) = old_off;
 
  346                                 recurseKnn(query, childLeft(n), rd, heap, off, maxError, allowSelfMatch);
 
  347                                 rd += - old_off*old_off + new_off*new_off;
 
  350                                         off.coeffRef(cd) = new_off;
 
  351                                         recurseKnn(query, childRight(n), rd, heap, off, maxError, allowSelfMatch);
 
  352                                         off.coeffRef(cd) = old_off;
 
  367         template<
typename T, 
typename CloudType>
 
  377                         if (elCount & (1 << i))
 
  380                 for (
int j = 0; j <= i; ++j)
 
  387         template<
typename T, 
typename CloudType>
 
  390                 const size_t count(last - first);
 
  394                         const int dim = -2-(first->index);
 
  395                         assert(pos < nodes.size());
 
  396                         nodes[pos] = 
Node(dim);
 
  405                         Vector mean(Vector::Zero(this->dim));
 
  408                         mean /= last - first;
 
  410                         Vector var(Vector::Zero(this->dim));
 
  412                                 var += (it->pos - mean).cwise() * (it->pos - mean);
 
  414                         cutDim = argMax<T>(var);
 
  419                         cutDim = argMax<T>(maxValues - minValues);
 
  423                 const size_t rightCount(count/2);
 
  424                 const size_t leftCount(count - rightCount);
 
  425                 assert(last - rightCount == first + leftCount);
 
  429                 nth_element(first, first + leftCount, last, 
CompareDim(cutDim));
 
  432                 const T cutVal((first+leftCount)->pos.coeff(cutDim));
 
  433                 nodes[pos] = 
Node(cutDim, cutVal);
 
  438                 Vector leftMaxValues(maxValues);
 
  439                 leftMaxValues[cutDim] = cutVal;
 
  441                 Vector rightMinValues(minValues);
 
  442                 rightMinValues[cutDim] = cutVal;
 
  445                 buildNodes(first, first + leftCount, childLeft(pos), minValues, leftMaxValues, balanceVariance);
 
  446                 buildNodes(first + leftCount, last, childRight(pos), rightMinValues, maxValues, balanceVariance);
 
  449         template<
typename T, 
typename CloudType>
 
  455                 buildPoints.reserve(
cloud.cols());
 
  456                 for (
int i = 0; i < 
cloud.cols(); ++i)
 
  471         template<
typename T, 
typename CloudType>
 
  476                 assert(nodes.size() > 0);
 
  478                 Vector off(Vector::Zero(query.size()));
 
  480                 statistics.lastQueryVisitCount = 0;
 
  482                 recurseKnn(query, 0, 0, heap, off, 1 + 
epsilon, allowSelfMatch);
 
  487                 statistics.totalVisitCount += statistics.lastQueryVisitCount;
 
  489                 return heap.getIndexes();
 
  492         template<
typename T, 
typename CloudType>
 
  495                 const Node& node(nodes[n]);
 
  496                 const int cd(node.
dim);
 
  498                 ++statistics.lastQueryVisitCount;
 
  504                         const int index(-(cd + 2));
 
  505                         const T dist(dist2<T>(query, cloud.col(index)));
 
  507                                 (allowSelfMatch || (dist > numeric_limits<T>::epsilon()))
 
  513                         const T old_off(off.coeff(cd));
 
  514                         const T new_off(query.coeff(cd) - node.
cutVal);
 
  517                                 recurseKnn(query, childRight(n), rd, heap, off, maxError, allowSelfMatch);
 
  518                                 rd += - old_off*old_off + new_off*new_off;
 
  521                                         off.coeffRef(cd) = new_off;
 
  522                                         recurseKnn(query, childLeft(n), rd, heap, off, maxError, allowSelfMatch);
 
  523                                         off.coeffRef(cd) = old_off;
 
  528                                 recurseKnn(query, childLeft(n), rd, heap, off, maxError, allowSelfMatch);
 
  529                                 rd += - old_off*old_off + new_off*new_off;
 
  532                                         off.coeffRef(cd) = new_off;
 
  533                                         recurseKnn(query, childRight(n), rd, heap, off, maxError, allowSelfMatch);
 
  534                                         off.coeffRef(cd) = old_off;
 
  549         template<
typename T, 
typename Heap, 
typename CloudType>
 
  552                 const size_t count(last - first);
 
  553                 const unsigned pos(nodes.size());
 
  558                         nodes.push_back(
Node(first->index));
 
  563                 const unsigned cutDim = argMax<T>(maxValues - minValues);
 
  564                 T cutVal((maxValues(cutDim) + minValues(cutDim))/2);
 
  571                 size_t rightStart(0);
 
  572                 while (rightStart < count && (first+rightStart)->pos.coeff(cutDim) < cutVal)
 
  578                         cutVal = first->pos.coeff(cutDim);
 
  581                 else if (rightStart == count)
 
  583                         rightStart = count - 1;
 
  584                         cutVal = (first + rightStart)->pos.coeff(cutDim);
 
  588                 Vector leftMaxValues(maxValues);
 
  589                 leftMaxValues[cutDim] = cutVal;
 
  591                 Vector rightMinValues(minValues);
 
  592                 rightMinValues[cutDim] = cutVal;
 
  595                 const size_t rightCount(count - rightStart);
 
  596                 const size_t leftCount(count - rightCount);
 
  599                 nodes.push_back(
Node(cutDim, cutVal, 0));
 
  602                 const unsigned __attribute__ ((unused)) leftChild = buildNodes(first, first + leftCount, minValues, leftMaxValues);
 
  603                 assert(leftChild == pos + 1);
 
  604                 const unsigned rightChild = buildNodes(first + leftCount, last, rightMinValues, maxValues);
 
  607                 nodes[pos].rightChild = rightChild;
 
  611         template<
typename T, 
typename Heap, 
typename CloudType>
 
  617                 buildPoints.reserve(
cloud.cols());
 
  618                 for (
int i = 0; i < 
cloud.cols(); ++i)
 
  633         template<
typename T, 
typename Heap, 
typename CloudType>
 
  638                 assert(nodes.size() > 0);
 
  640                 Vector off(Vector::Zero(query.size()));
 
  642                 statistics.lastQueryVisitCount = 0;
 
  644                 recurseKnn(query, 0, 0, heap, off, 1+
epsilon, allowSelfMatch);
 
  649                 statistics.totalVisitCount += statistics.lastQueryVisitCount;
 
  651                 return heap.getIndexes();
 
  654         template<
typename T, 
typename Heap, 
typename CloudType>
 
  658                 assert(nodes.size() > 0);
 
  660                 assert(nodes.size() > 0);
 
  665                 const int colCount(query.cols());
 
  667                 for (
int i = 0; i < colCount; ++i)
 
  674                         statistics.lastQueryVisitCount = 0;
 
  676                         recurseKnn(
q, 0, 0, heap, off, 1+
epsilon, allowSelfMatch);
 
  681                         result.col(i) = heap.getIndexes();
 
  683                         statistics.totalVisitCount += statistics.lastQueryVisitCount;
 
  689         template<
typename T, 
typename Heap, 
typename CloudType>
 
  692                 const Node& node(nodes[n]);
 
  697                         const unsigned index(node.
ptIndex);
 
  701                         const T* qPtr(&query.coeff(0));
 
  702                         const T* dPtr(&cloud.coeff(0, index));
 
  703                         const int dim(query.size());
 
  704                         for (
int i = 0; i < dim; ++i)
 
  706                                 const T diff(*qPtr - *dPtr);
 
  710                         if ((dist < heap.headValue()) &&
 
  711                                 (allowSelfMatch || (dist > numeric_limits<T>::epsilon()))
 
  713                                 heap.replaceHead(index, dist);
 
  717                         const unsigned cd(node.
dim);
 
  718                         const T old_off(off.coeff(cd));
 
  719                         const T new_off(query.coeff(cd) - node.
cutVal);
 
  722                                 recurseKnn(query, node.
rightChild, rd, heap, off, maxError, allowSelfMatch);
 
  723                                 rd += - old_off*old_off + new_off*new_off;
 
  724                                 if (rd * maxError < heap.headValue())
 
  726                                         off.coeffRef(cd) = new_off;
 
  727                                         recurseKnn(query, n + 1, rd, heap, off, maxError, allowSelfMatch);
 
  728                                         off.coeffRef(cd) = old_off;
 
  733                                 recurseKnn(query, n+1, rd, heap, off, maxError, allowSelfMatch);
 
  734                                 rd += - old_off*old_off + new_off*new_off;
 
  735                                 if (rd * maxError < heap.headValue())
 
  737                                         off.coeffRef(cd) = new_off;
 
  738                                         recurseKnn(query, node.
rightChild, rd, heap, off, maxError, allowSelfMatch);
 
  739                                         off.coeffRef(cd) = old_off;
 
  760         template<
typename T, 
typename CloudType>
 
  763                 const size_t count(last - first);
 
  764                 const unsigned pos(nodes.size());
 
  769                         const int dim = -1-(first->index);
 
  770                         nodes.push_back(
Node(dim));
 
  775                 const int cutDim = argMax<T>(maxValues - minValues);
 
  776                 T cutVal((maxValues(cutDim) + minValues(cutDim))/2);
 
  783                 size_t rightStart(0);
 
  784                 while (rightStart < count && (first+rightStart)->pos.coeff(cutDim) < cutVal)
 
  790                         cutVal = first->pos.coeff(cutDim);
 
  793                 else if (rightStart == count)
 
  795                         rightStart = count - 1;
 
  796                         cutVal = (first + rightStart)->pos.coeff(cutDim);
 
  800                 Vector leftMaxValues(maxValues);
 
  801                 leftMaxValues[cutDim] = cutVal;
 
  803                 Vector rightMinValues(minValues);
 
  804                 rightMinValues[cutDim] = cutVal;
 
  807                 const size_t rightCount(count - rightStart);
 
  808                 const size_t leftCount(count - rightCount);
 
  811                 nodes.push_back(
Node(cutDim, cutVal, minValues.coeff(cutDim), maxValues.coeff(cutDim)));
 
  814                 const unsigned __attribute__ ((unused)) leftChild = buildNodes(first, first + leftCount, minValues, leftMaxValues);
 
  815                 assert(leftChild == pos + 1);
 
  816                 const unsigned rightChild = buildNodes(first + leftCount, last, rightMinValues, maxValues);
 
  819                 nodes[pos].rightChild = rightChild;
 
  823         template<
typename T, 
typename CloudType>
 
  829                 buildPoints.reserve(
cloud.cols());
 
  830                 for (
int i = 0; i < 
cloud.cols(); ++i)
 
  845         template<
typename T, 
typename CloudType>
 
  850                 assert(nodes.size() > 0);
 
  853                 statistics.lastQueryVisitCount = 0;
 
  855                 recurseKnn(query, 0, 0, heap, 1+
epsilon, allowSelfMatch);
 
  860                 statistics.totalVisitCount += statistics.lastQueryVisitCount;
 
  862                 return heap.getIndexes();
 
  865         template<
typename T, 
typename CloudType>
 
  868                 const Node& node(nodes[n]);
 
  869                 const int cd(node.
dim);
 
  871                 ++statistics.lastQueryVisitCount;
 
  875                         const int index(-(cd + 1));
 
  876                         const T dist(dist2<T>(query, cloud.col(index)));
 
  878                                 (allowSelfMatch || (dist > numeric_limits<T>::epsilon()))
 
  884                         const T q_val(query.coeff(cd));
 
  885                         const T cut_diff(q_val - node.
cutVal);
 
  888                                 recurseKnn(query, n+1, rd, heap, maxError, allowSelfMatch);
 
  894                                 rd += cut_diff*cut_diff - box_diff*box_diff;
 
  897                                         recurseKnn(query, node.
rightChild, rd, heap, maxError, allowSelfMatch);
 
  901                                 recurseKnn(query, node.
rightChild, rd, heap, maxError, allowSelfMatch);
 
  907                                 rd += cut_diff*cut_diff - box_diff*box_diff;
 
  910                                         recurseKnn(query, n + 1, rd, heap, maxError, allowSelfMatch);