src/kd_fix_rad_search.cpp
author Dmitriy Morozov <dmitriy@mrzv.org>
Fri, 17 Jul 2009 13:54:30 -0700 (2009-07-17)
changeset 3 f1e962ffa1c2
parent 0 e2bb6f169431
permissions -rw-r--r--
ANNkd_tree:annkSearch() is reentrant, in particular it works with OpenMP
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
     1
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
     2
// File:			kd_fix_rad_search.cpp
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
     3
// Programmer:		Sunil Arya and David Mount
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
     4
// Description:		Standard kd-tree fixed-radius kNN search
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
     5
// Last modified:	05/03/05 (Version 1.1)
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
     6
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
     7
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
     8
// David Mount.  All Rights Reserved.
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
     9
// 
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    10
// This software and related documentation is part of the Approximate
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    11
// Nearest Neighbor Library (ANN).  This software is provided under
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    12
// the provisions of the Lesser GNU Public License (LGPL).  See the
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    13
// file ../ReadMe.txt for further information.
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    14
// 
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    15
// The University of Maryland (U.M.) and the authors make no
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    16
// representations about the suitability or fitness of this software for
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    17
// any purpose.  It is provided "as is" without express or implied
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    18
// warranty.
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    19
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    20
// History:
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    21
//	Revision 1.1  05/03/05
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    22
//		Initial release
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    23
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    24
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    25
#include "kd_fix_rad_search.h"			// kd fixed-radius search decls
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    26
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    27
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    28
//	Approximate fixed-radius k nearest neighbor search
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    29
//		The squared radius is provided, and this procedure finds the
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    30
//		k nearest neighbors within the radius, and returns the total
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    31
//		number of points lying within the radius.
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    32
//
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    33
//		The method used for searching the kd-tree is a variation of the
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    34
//		nearest neighbor search used in kd_search.cpp, except that the
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    35
//		radius of the search ball is known.  We refer the reader to that
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    36
//		file for the explanation of the recursive search procedure.
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    37
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    38
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    39
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    40
//		To keep argument lists short, a number of global variables
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    41
//		are maintained which are common to all the recursive calls.
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    42
//		These are given below.
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    43
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    44
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    45
int				ANNkdFRDim;				// dimension of space
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    46
ANNpoint		ANNkdFRQ;				// query point
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    47
ANNdist			ANNkdFRSqRad;			// squared radius search bound
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    48
double			ANNkdFRMaxErr;			// max tolerable squared error
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    49
ANNpointArray	ANNkdFRPts;				// the points
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    50
ANNmin_k*		ANNkdFRPointMK;			// set of k closest points
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    51
int				ANNkdFRPtsVisited;		// total points visited
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    52
int				ANNkdFRPtsInRange;		// number of points in the range
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    53
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    54
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    55
//	annkFRSearch - fixed radius search for k nearest neighbors
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    56
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    57
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    58
int ANNkd_tree::annkFRSearch(
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    59
	ANNpoint			q,				// the query point
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    60
	ANNdist				sqRad,			// squared radius search bound
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    61
	int					k,				// number of near neighbors to return
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    62
	ANNidxArray			nn_idx,			// nearest neighbor indices (returned)
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    63
	ANNdistArray		dd,				// the approximate nearest neighbor
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    64
	double				eps)			// the error bound
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    65
{
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    66
	ANNkdFRDim = dim;					// copy arguments to static equivs
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    67
	ANNkdFRQ = q;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    68
	ANNkdFRSqRad = sqRad;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    69
	ANNkdFRPts = pts;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    70
	ANNkdFRPtsVisited = 0;				// initialize count of points visited
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    71
	ANNkdFRPtsInRange = 0;				// ...and points in the range
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    72
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    73
	ANNkdFRMaxErr = ANN_POW(1.0 + eps);
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    74
	ANN_FLOP(2)							// increment floating op count
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    75
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    76
	ANNkdFRPointMK = new ANNmin_k(k);	// create set for closest k points
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    77
										// search starting at the root
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    78
	root->ann_FR_search(annBoxDistance(q, bnd_box_lo, bnd_box_hi, dim));
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    79
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    80
	for (int i = 0; i < k; i++) {		// extract the k-th closest points
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    81
		if (dd != NULL)
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    82
			dd[i] = ANNkdFRPointMK->ith_smallest_key(i);
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    83
		if (nn_idx != NULL)
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    84
			nn_idx[i] = ANNkdFRPointMK->ith_smallest_info(i);
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    85
	}
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    86
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    87
	delete ANNkdFRPointMK;				// deallocate closest point set
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    88
	return ANNkdFRPtsInRange;			// return final point count
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    89
}
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    90
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    91
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    92
//	kd_split::ann_FR_search - search a splitting node
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    93
//		Note: This routine is similar in structure to the standard kNN
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    94
//		search.  It visits the subtree that is closer to the query point
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    95
//		first.  For fixed-radius search, there is no benefit in visiting
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    96
//		one subtree before the other, but we maintain the same basic
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    97
//		code structure for the sake of uniformity.
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    98
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
    99
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   100
void ANNkd_split::ann_FR_search(ANNdist box_dist)
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   101
{
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   102
										// check dist calc term condition
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   103
	if (ANNmaxPtsVisited != 0 && ANNkdFRPtsVisited > ANNmaxPtsVisited) return;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   104
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   105
										// distance to cutting plane
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   106
	ANNcoord cut_diff = ANNkdFRQ[cut_dim] - cut_val;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   107
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   108
	if (cut_diff < 0) {					// left of cutting plane
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   109
		child[ANN_LO]->ann_FR_search(box_dist);// visit closer child first
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   110
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   111
		ANNcoord box_diff = cd_bnds[ANN_LO] - ANNkdFRQ[cut_dim];
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   112
		if (box_diff < 0)				// within bounds - ignore
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   113
			box_diff = 0;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   114
										// distance to further box
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   115
		box_dist = (ANNdist) ANN_SUM(box_dist,
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   116
				ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff)));
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   117
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   118
										// visit further child if in range
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   119
		if (box_dist * ANNkdFRMaxErr <= ANNkdFRSqRad)
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   120
			child[ANN_HI]->ann_FR_search(box_dist);
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   121
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   122
	}
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   123
	else {								// right of cutting plane
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   124
		child[ANN_HI]->ann_FR_search(box_dist);// visit closer child first
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   125
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   126
		ANNcoord box_diff = ANNkdFRQ[cut_dim] - cd_bnds[ANN_HI];
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   127
		if (box_diff < 0)				// within bounds - ignore
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   128
			box_diff = 0;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   129
										// distance to further box
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   130
		box_dist = (ANNdist) ANN_SUM(box_dist,
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   131
				ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff)));
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   132
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   133
										// visit further child if close enough
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   134
		if (box_dist * ANNkdFRMaxErr <= ANNkdFRSqRad)
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   135
			child[ANN_LO]->ann_FR_search(box_dist);
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   136
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   137
	}
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   138
	ANN_FLOP(13)						// increment floating ops
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   139
	ANN_SPL(1)							// one more splitting node visited
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   140
}
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   141
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   142
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   143
//	kd_leaf::ann_FR_search - search points in a leaf node
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   144
//		Note: The unreadability of this code is the result of
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   145
//		some fine tuning to replace indexing by pointer operations.
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   146
//----------------------------------------------------------------------
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   147
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   148
void ANNkd_leaf::ann_FR_search(ANNdist box_dist)
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   149
{
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   150
	register ANNdist dist;				// distance to data point
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   151
	register ANNcoord* pp;				// data coordinate pointer
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   152
	register ANNcoord* qq;				// query coordinate pointer
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   153
	register ANNcoord t;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   154
	register int d;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   155
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   156
	for (int i = 0; i < n_pts; i++) {	// check points in bucket
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   157
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   158
		pp = ANNkdFRPts[bkt[i]];		// first coord of next data point
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   159
		qq = ANNkdFRQ;					// first coord of query point
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   160
		dist = 0;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   161
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   162
		for(d = 0; d < ANNkdFRDim; d++) {
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   163
			ANN_COORD(1)				// one more coordinate hit
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   164
			ANN_FLOP(5)					// increment floating ops
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   165
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   166
			t = *(qq++) - *(pp++);		// compute length and adv coordinate
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   167
										// exceeds dist to k-th smallest?
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   168
			if( (dist = ANN_SUM(dist, ANN_POW(t))) > ANNkdFRSqRad) {
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   169
				break;
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   170
			}
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   171
		}
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   172
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   173
		if (d >= ANNkdFRDim &&					// among the k best?
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   174
		   (ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   175
												// add it to the list
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   176
			ANNkdFRPointMK->insert(dist, bkt[i]);
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   177
			ANNkdFRPtsInRange++;				// increment point count
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   178
		}
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   179
	}
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   180
	ANN_LEAF(1)							// one more leaf node visited
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   181
	ANN_PTS(n_pts)						// increment points visited
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   182
	ANNkdFRPtsVisited += n_pts;			// increment number of points visited
e2bb6f169431 Initial commit: ANN 1.1.1
Dmitriy Morozov <dmitriy@mrzv.org>
parents:
diff changeset
   183
}