93 dist = (*w)[0] * fabs(p[0] - q[0]);
94 for (i = 1; i < p.size(); i++) {
95 test = (*w)[i] * fabs(p[i] - q[i]);
100 dist = fabs(p[0] - q[0]);
101 for (i = 1; i < p.size(); i++) {
102 test = fabs(p[i] - q[i]);
112 return (*w)[dim] * fabs(x -
y);
139 for (i = 0; i < p.size(); i++)
140 dist += (*w)[i] * fabs(p[i] - q[i]);
142 for (i = 0; i < p.size(); i++)
143 dist += fabs(p[i] - q[i]);
150 return (*w)[dim] * fabs(x -
y);
177 for (i = 0; i < p.size(); i++)
178 dist += (*w)[i] * (p[i] - q[i]) * (p[i] - q[i]);
180 for (i = 0; i < p.size(); i++)
181 dist += (p[i] - q[i]) * (p[i] - q[i]);
188 return (*w)[dim] * (x -
y) * (x -
y);
190 return (x -
y) * (x -
y);
209 dimension = nodes->begin()->point.size();
213 this->distance_type = -1;
216 lobound = nodes->begin()->point;
217 upbound = nodes->begin()->point;
218 for (i = 1; i < nodes->size(); i++) {
221 if (lobound[j] > val)
223 if (upbound[j] < val)
236 this->distance_type = distance_type_;
237 if (distance_type_ == 0) {
239 }
else if (distance_type_ == 1) {
251 kdtree_node *KdTree::build_tree(
size_t depth,
size_t a,
size_t b)
256 node->lobound = lobound;
257 node->upbound = upbound;
265 compare_dimension(
node->cutdim));
270 temp = upbound[
node->cutdim];
271 upbound[
node->cutdim] = cutval;
272 node->loson = build_tree(depth + 1, a, m);
273 upbound[
node->cutdim] = temp;
276 temp = lobound[
node->cutdim];
277 lobound[
node->cutdim] = cutval;
278 node->hison = build_tree(depth + 1, m + 1, b);
279 lobound[
node->cutdim] = temp;
301 searchpredicate = pred;
307 throw std::invalid_argument(
"kdtree::k_nearest_neighbors(): point must be of same dimension as "
311 neighborheap =
new std::priority_queue<nn4heap, std::vector<nn4heap>,
compare_nn4heap>();
315 for (i = 0; i < k; i++) {
316 if (!(searchpredicate && !(*searchpredicate)(
allnodes[i])))
320 neighbor_search(point,
root, k);
325 while (!neighborheap->empty()) {
326 i = neighborheap->top().dataindex;
327 d = neighborheap->top().distance;
330 distances->push_back(d);
334 for (i = 0; i < k / 2; i++) {
336 (*result)[i] = (*result)[k - 1 - i];
337 (*result)[k - 1 - i] = temp;
338 temp_dist = (*distances)[i];
339 (*distances)[i] = (*distances)[k - 1 - i];
340 (*distances)[k - 1 - i] = temp_dist;
357 throw std::invalid_argument(
"kdtree::k_nearest_neighbors(): point must be of same dimension as "
359 if (this->distance_type == 2) {
366 range_search(point,
root, r);
369 for (std::vector<size_t>::iterator i = range_result.begin(); i != range_result.end(); ++i) {
374 range_result.clear();
384 double curdist, dist;
387 if (!(searchpredicate && !(*searchpredicate)(
allnodes[
node->dataindex]))) {
388 if (neighborheap->size() < k) {
389 neighborheap->push(
nn4heap(
node->dataindex, curdist));
390 }
else if (curdist < neighborheap->top().distance) {
392 neighborheap->push(nn4heap(
node->dataindex, curdist));
398 if (neighbor_search(point,
node->loson, k))
402 if (neighbor_search(point,
node->hison, k))
406 if (neighborheap->size() < k) {
407 dist = std::numeric_limits<double>::max();
409 dist = neighborheap->top().distance;
412 if (
node->hison && bounds_overlap_ball(point, dist,
node->hison))
413 if (neighbor_search(point,
node->hison, k))
416 if (
node->loson && bounds_overlap_ball(point, dist,
node->loson))
417 if (neighbor_search(point,
node->loson, k))
421 if (neighborheap->size() == k)
422 dist = neighborheap->top().distance;
423 return ball_within_bounds(point, dist,
node);
430 void KdTree::range_search(
const CoordPoint &point, kdtree_node *
node,
double r)
432 double curdist = distance->
distance(point,
node->point);
434 range_result.push_back(
node->dataindex);
436 if (
node->loson != NULL && this->bounds_overlap_ball(point, r,
node->loson)) {
437 range_search(point,
node->loson, r);
439 if (
node->hison != NULL && this->bounds_overlap_ball(point, r,
node->hison)) {
440 range_search(point,
node->hison, r);
446 bool KdTree::bounds_overlap_ball(
const CoordPoint &point,
double dist, kdtree_node *
node)
448 double distsum = 0.0;
451 if (point[i] <
node->lobound[i]) {
455 }
else if (point[i] >
node->upbound[i]) {
466 bool KdTree::ball_within_bounds(
const CoordPoint &point,
double dist, kdtree_node *
node)