void ksearch_common(Point q, unsigned int k, long unsigned int query_point_index, qknn &que, float Eps) { Point bound_box_lower_corner, bound_box_upper_corner; Point low, high; que.set_size(k); eps=(float) 1.0+Eps; if (query_point_index >= (k)) query_point_index -= (k); else query_point_index=0; long unsigned int initial_scan_upper_range=query_point_index+2*k+1; if (initial_scan_upper_range > (long unsigned int)points.size()) initial_scan_upper_range = (long unsigned int)points.size(); low = points[query_point_index]; high = points[initial_scan_upper_range-1]; for (long unsigned int i=query_point_index; i<initial_scan_upper_range; ++i) { que.update(points[i].sqr_dist(q), pointers[i]); } compute_bounding_box(q, bound_box_lower_corner, bound_box_upper_corner, sqrt(que.topdist())); if (lt(bound_box_upper_corner, high) && lt(low,bound_box_lower_corner)) { return; } //Recurse through the entire set recurse(0, points.size(), q, que, bound_box_lower_corner, bound_box_upper_corner, query_point_index, initial_scan_upper_range); }
inline void recurse(long unsigned int s, // Starting index long unsigned int n, // Number of points Point q, // Query point qknn &ans, // Answer que Point &bound_box_lower_corner, Point &bound_box_upper_corner, long unsigned int initial_scan_lower_range, long unsigned int initial_scan_upper_range) { if (n < 4) { if (n == 0) return; bool update=false; for (long unsigned int i=0; i < n; ++i) { if ((s+i >= initial_scan_lower_range) && (s+i < initial_scan_upper_range)) continue; update = ans.update(points[s+i].sqr_dist(q), pointers[s+i]) || update; } if (update) compute_bounding_box(q, bound_box_lower_corner, bound_box_upper_corner, sqrt(ans.topdist())); return; } if ((s+n/2 >= initial_scan_lower_range) && (s+n/2 < initial_scan_upper_range)) { } else if (ans.update(points[s+n/2].sqr_dist(q), pointers[s+n/2])) compute_bounding_box(q, bound_box_lower_corner, bound_box_upper_corner, sqrt(ans.topdist())); double dsqb = lt.dist_sq_to_quad_box(q,points[s], points[s+n-1]); if (dsqb > ans.topdist()) return; if (lt(q,points[s+n/2])) { recurse(s, n/2, q, ans, bound_box_lower_corner, bound_box_upper_corner, initial_scan_lower_range, initial_scan_upper_range); if (lt(points[s+n/2],bound_box_upper_corner)) recurse(s+n/2+1,n-n/2-1, q, ans, bound_box_lower_corner, bound_box_upper_corner, initial_scan_lower_range, initial_scan_upper_range); } else { recurse(s+n/2+1, n-n/2-1, q, ans, bound_box_lower_corner, bound_box_upper_corner, initial_scan_lower_range, initial_scan_upper_range); if (lt(bound_box_lower_corner,points[s+n/2])) recurse(s, n/2, q, ans, bound_box_lower_corner, bound_box_upper_corner, initial_scan_lower_range, initial_scan_upper_range); } }
void sfcnn_knng_work<Point>::recurse(int s, // Starting index int n, // Number of points long int q, qknn &ans, // Answer que Point &bound_box_lower_corner, Point &bound_box_upper_corner, int initial_scan_lower_range, int initial_scan_upper_range, zorder_lt<Point> <) { double distance; if(n < 4) { if(n == 0) return; bool update=false; for(int i=0;i < n;++i) { if((s+i >= initial_scan_lower_range) && (s+i < initial_scan_upper_range)) continue; distance = points[q].sqr_dist(points[s+i]); update = ans.update(distance, pointers[s+i]) || update; } if(update) compute_bounding_box(points[q], bound_box_lower_corner, bound_box_upper_corner, sqrt(ans.topdist())); return; } if((s+n/2 >= initial_scan_lower_range) && (s+n/2 < initial_scan_upper_range)) { } else { distance = points[q].sqr_dist(points[s+n/2]); if(ans.update(distance, pointers[s+n/2])) compute_bounding_box(points[q], bound_box_lower_corner, bound_box_upper_corner, sqrt(ans.topdist())); } if((lt.dist_sq_to_quad_box(points[q],points[s], points[s+n-1])) > ans.topdist()) return; if(lt(points[q],points[s+n/2])) { recurse(s, n/2, q, ans, bound_box_lower_corner, bound_box_upper_corner, initial_scan_lower_range, initial_scan_upper_range, lt); if(lt(points[s+n/2],bound_box_upper_corner)) recurse(s+n/2+1,n-n/2-1, q, ans, bound_box_lower_corner, bound_box_upper_corner, initial_scan_lower_range, initial_scan_upper_range, lt); } else { recurse(s+n/2+1, n-n/2-1, q, ans, bound_box_lower_corner, bound_box_upper_corner, initial_scan_lower_range, initial_scan_upper_range, lt); if(lt(bound_box_lower_corner,points[s+n/2])) recurse(s, n/2, q, ans, bound_box_lower_corner, bound_box_upper_corner, initial_scan_lower_range, initial_scan_upper_range, lt); } };