ANN.h
上传用户:chinafayin
上传日期:2022-04-05
资源大小:153k
文件大小:34k
源码类别:

并行计算

开发平台:

Visual C++

  1. //----------------------------------------------------------------------
  2. // File: ANN.h
  3. // Programmer: Sunil Arya and David Mount
  4. // Last modified: 05/03/05 (Release 1.1)
  5. // Description: Basic include file for approximate nearest
  6. // neighbor searching.
  7. //----------------------------------------------------------------------
  8. // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
  9. // David Mount.  All Rights Reserved.
  10. // 
  11. // This software and related documentation is part of the Approximate
  12. // Nearest Neighbor Library (ANN).  This software is provided under
  13. // the provisions of the Lesser GNU Public License (LGPL).  See the
  14. // file ../ReadMe.txt for further information.
  15. // 
  16. // The University of Maryland (U.M.) and the authors make no
  17. // representations about the suitability or fitness of this software for
  18. // any purpose.  It is provided "as is" without express or implied
  19. // warranty.
  20. //----------------------------------------------------------------------
  21. // History:
  22. // Revision 0.1  03/04/98
  23. // Initial release
  24. // Revision 1.0  04/01/05
  25. // Added copyright and revision information
  26. // Added ANNcoordPrec for coordinate precision.
  27. // Added methods theDim, nPoints, maxPoints, thePoints to ANNpointSet.
  28. // Cleaned up C++ structure for modern compilers
  29. // Revision 1.1  05/03/05
  30. // Added fixed-radius k-NN searching
  31. //----------------------------------------------------------------------
  32. //----------------------------------------------------------------------
  33. // ANN - approximate nearest neighbor searching
  34. // ANN is a library for approximate nearest neighbor searching,
  35. // based on the use of standard and priority search in kd-trees
  36. // and balanced box-decomposition (bbd) trees. Here are some
  37. // references to the main algorithmic techniques used here:
  38. //
  39. // kd-trees:
  40. // Friedman, Bentley, and Finkel, ``An algorithm for finding
  41. // best matches in logarithmic expected time,'' ACM
  42. // Transactions on Mathematical Software, 3(3):209-226, 1977.
  43. //
  44. // Priority search in kd-trees:
  45. // Arya and Mount, ``Algorithms for fast vector quantization,''
  46. // Proc. of DCC '93: Data Compression Conference, eds. J. A.
  47. // Storer and M. Cohn, IEEE Press, 1993, 381-390.
  48. //
  49. // Approximate nearest neighbor search and bbd-trees:
  50. // Arya, Mount, Netanyahu, Silverman, and Wu, ``An optimal
  51. // algorithm for approximate nearest neighbor searching,''
  52. // 5th Ann. ACM-SIAM Symposium on Discrete Algorithms,
  53. // 1994, 573-582.
  54. //----------------------------------------------------------------------
  55. #ifndef ANN_H
  56. #define ANN_H
  57. /*#ifdef WIN32
  58.   //----------------------------------------------------------------------
  59.   // For Microsoft Visual C++, externally accessible symbols must be
  60.   // explicitly indicated with DLL_API, which is somewhat like "extern."
  61.   //
  62.   // The following ifdef block is the standard way of creating macros
  63.   // which make exporting from a DLL simpler. All files within this DLL
  64.   // are compiled with the DLL_EXPORTS preprocessor symbol defined on the
  65.   // command line. In contrast, projects that use (or import) the DLL
  66.   // objects do not define the DLL_EXPORTS symbol. This way any other
  67.   // project whose source files include this file see DLL_API functions as
  68.   // being imported from a DLL, wheras this DLL sees symbols defined with
  69.   // this macro as being exported.
  70.   //----------------------------------------------------------------------
  71.   #ifdef DLL_EXPORTS
  72.  #define DLL_API __declspec(dllexport)
  73.   #else
  74. #define DLL_API __declspec(dllimport)
  75.   #endif
  76.   //----------------------------------------------------------------------
  77.   // DLL_API is ignored for all other systems
  78.   //----------------------------------------------------------------------
  79. #else*/
  80.   #define DLL_API
  81. //#endif
  82. #if defined(WIN32)
  83. #define ANN_THREAD_LOCAL __declspec(thread)
  84. #else
  85. #define ANN_THREAD_LOCAL __thread
  86. #endif
  87. //----------------------------------------------------------------------
  88. //  basic includes
  89. //----------------------------------------------------------------------
  90. #include <cmath> // math includes
  91. #include <iostream> // I/O streams
  92. //----------------------------------------------------------------------
  93. // Limits
  94. // There are a number of places where we use the maximum double value as
  95. // default initializers (and others may be used, depending on the
  96. // data/distance representation). These can usually be found in limits.h
  97. // (as LONG_MAX, INT_MAX) or in float.h (as DBL_MAX, FLT_MAX).
  98. //
  99. // Not all systems have these files.  If you are using such a system,
  100. // you should set the preprocessor symbol ANN_NO_LIMITS_H when
  101. // compiling, and modify the statements below to generate the
  102. // appropriate value. For practical purposes, this does not need to be
  103. // the maximum double value. It is sufficient that it be at least as
  104. // large than the maximum squared distance between between any two
  105. // points.
  106. //----------------------------------------------------------------------
  107. #ifdef ANN_NO_LIMITS_H // limits.h unavailable
  108.   #include <cvalues> // replacement for limits.h
  109.   const double ANN_DBL_MAX = MAXDOUBLE; // insert maximum double
  110. #else
  111.   #include <climits>
  112.   #include <cfloat>
  113.   const double ANN_DBL_MAX = DBL_MAX;
  114. #endif
  115. #define ANNversion  "1.1.1" // ANN version and information
  116. #define ANNversionCmt ""
  117. #define ANNcopyright "David M. Mount and Sunil Arya"
  118. #define ANNlatestRev "Aug 4, 2006"
  119. //----------------------------------------------------------------------
  120. // ANNbool
  121. // This is a simple boolean type. Although ANSI C++ is supposed
  122. // to support the type bool, some compilers do not have it.
  123. //----------------------------------------------------------------------
  124. enum ANNbool {ANNfalse = 0, ANNtrue = 1}; // ANN boolean type (non ANSI C++)
  125. //----------------------------------------------------------------------
  126. // ANNcoord, ANNdist
  127. // ANNcoord and ANNdist are the types used for representing
  128. // point coordinates and distances.  They can be modified by the
  129. // user, with some care.  It is assumed that they are both numeric
  130. // types, and that ANNdist is generally of an equal or higher type
  131. // from ANNcoord. A variable of type ANNdist should be large
  132. // enough to store the sum of squared components of a variable
  133. // of type ANNcoord for the number of dimensions needed in the
  134. // application.  For example, the following combinations are
  135. // legal:
  136. //
  137. // ANNcoord ANNdist
  138. // --------- -------------------------------
  139. // short short, int, long, float, double
  140. // int int, long, float, double
  141. // long long, float, double
  142. // float float, double
  143. // double double
  144. //
  145. // It is the user's responsibility to make sure that overflow does
  146. // not occur in distance calculation.
  147. //----------------------------------------------------------------------
  148. typedef double ANNcoord; // coordinate data type
  149. typedef double ANNdist; // distance data type
  150. //----------------------------------------------------------------------
  151. // ANNidx
  152. // ANNidx is a point index.  When the data structure is built, the
  153. // points are given as an array.  Nearest neighbor results are
  154. // returned as an integer index into this array.  To make it
  155. // clearer when this is happening, we define the integer type
  156. // ANNidx.  Indexing starts from 0.
  157. //
  158. // For fixed-radius near neighbor searching, it is possible that
  159. // there are not k nearest neighbors within the search radius.  To
  160. // indicate this, the algorithm returns ANN_NULL_IDX as its result.
  161. // It should be distinguishable from any valid array index.
  162. //----------------------------------------------------------------------
  163. typedef int ANNidx; // point index
  164. const ANNidx ANN_NULL_IDX = -1; // a NULL point index
  165. //----------------------------------------------------------------------
  166. // Infinite distance:
  167. // The code assumes that there is an "infinite distance" which it
  168. // uses to initialize distances before performing nearest neighbor
  169. // searches.  It should be as larger or larger than any legitimate
  170. // nearest neighbor distance.
  171. //
  172. // On most systems, these should be found in the standard include
  173. // file <limits.h> or possibly <float.h>.  If you do not have these
  174. // file, some suggested values are listed below, assuming 64-bit
  175. // long, 32-bit int and 16-bit short.
  176. //
  177. // ANNdist ANN_DIST_INF Values (see <limits.h> or <float.h>)
  178. // ------- ------------ ------------------------------------
  179. // double DBL_MAX 1.79769313486231570e+308
  180. // float FLT_MAX 3.40282346638528860e+38
  181. // long LONG_MAX 0x7fffffffffffffff
  182. // int INT_MAX 0x7fffffff
  183. // short SHRT_MAX 0x7fff
  184. //----------------------------------------------------------------------
  185. const ANNdist ANN_DIST_INF = ANN_DBL_MAX;
  186. //----------------------------------------------------------------------
  187. // Significant digits for tree dumps:
  188. // When floating point coordinates are used, the routine that dumps
  189. // a tree needs to know roughly how many significant digits there
  190. // are in a ANNcoord, so it can output points to full precision.
  191. // This is defined to be ANNcoordPrec.  On most systems these
  192. // values can be found in the standard include files <limits.h> or
  193. // <float.h>.  For integer types, the value is essentially ignored.
  194. //
  195. // ANNcoord ANNcoordPrec Values (see <limits.h> or <float.h>)
  196. // -------- ------------ ------------------------------------
  197. // double  DBL_DIG 15
  198. // float  FLT_DIG 6
  199. // long  doesn't matter 19
  200. // int  doesn't matter 10
  201. // short  doesn't matter 5
  202. //----------------------------------------------------------------------
  203. #ifdef DBL_DIG // number of sig. bits in ANNcoord
  204. const int  ANNcoordPrec = DBL_DIG;
  205. #else
  206. const int  ANNcoordPrec = 15; // default precision
  207. #endif
  208. //----------------------------------------------------------------------
  209. // Self match?
  210. // In some applications, the nearest neighbor of a point is not
  211. // allowed to be the point itself. This occurs, for example, when
  212. // computing all nearest neighbors in a set.  By setting the
  213. // parameter ANN_ALLOW_SELF_MATCH to ANNfalse, the nearest neighbor
  214. // is the closest point whose distance from the query point is
  215. // strictly positive.
  216. //----------------------------------------------------------------------
  217. const ANNbool ANN_ALLOW_SELF_MATCH = ANNtrue;
  218. //----------------------------------------------------------------------
  219. // Norms and metrics:
  220. // ANN supports any Minkowski norm for defining distance.  In
  221. // particular, for any p >= 1, the L_p Minkowski norm defines the
  222. // length of a d-vector (v0, v1, ..., v(d-1)) to be
  223. //
  224. // (|v0|^p + |v1|^p + ... + |v(d-1)|^p)^(1/p),
  225. //
  226. // (where ^ denotes exponentiation, and |.| denotes absolute
  227. // value).  The distance between two points is defined to be the
  228. // norm of the vector joining them.  Some common distance metrics
  229. // include
  230. //
  231. // Euclidean metric p = 2
  232. // Manhattan metric p = 1
  233. // Max metric p = infinity
  234. //
  235. // In the case of the max metric, the norm is computed by taking
  236. // the maxima of the absolute values of the components.  ANN is
  237. // highly "coordinate-based" and does not support general distances
  238. // functions (e.g. those obeying just the triangle inequality).  It
  239. // also does not support distance functions based on
  240. // inner-products.
  241. //
  242. // For the purpose of computing nearest neighbors, it is not
  243. // necessary to compute the final power (1/p).  Thus the only
  244. // component that is used by the program is |v(i)|^p.
  245. //
  246. // ANN parameterizes the distance computation through the following
  247. // macros.  (Macros are used rather than procedures for
  248. // efficiency.) Recall that the distance between two points is
  249. // given by the length of the vector joining them, and the length
  250. // or norm of a vector v is given by formula:
  251. //
  252. // |v| = ROOT(POW(v0) # POW(v1) # ... # POW(v(d-1)))
  253. //
  254. // where ROOT, POW are unary functions and # is an associative and
  255. // commutative binary operator mapping the following types:
  256. //
  257. // ** POW: ANNcoord --> ANNdist
  258. // ** #: ANNdist x ANNdist --> ANNdist
  259. // ** ROOT: ANNdist (>0) --> double
  260. //
  261. // For early termination in distance calculation (partial distance
  262. // calculation) we assume that POW and # together are monotonically
  263. // increasing on sequences of arguments, meaning that for all
  264. // v0..vk and y:
  265. //
  266. // POW(v0) #...# POW(vk) <= (POW(v0) #...# POW(vk)) # POW(y).
  267. //
  268. // Incremental Distance Calculation:
  269. // The program uses an optimized method of computing distances for
  270. // kd-trees and bd-trees, called incremental distance calculation.
  271. // It is used when distances are to be updated when only a single
  272. // coordinate of a point has been changed.  In order to use this,
  273. // we assume that there is an incremental update function DIFF(x,y)
  274. // for #, such that if:
  275. //
  276. // s = x0 # ... # xi # ... # xk 
  277. //
  278. // then if s' is equal to s but with xi replaced by y, that is, 
  279. //
  280. // s' = x0 # ... # y # ... # xk
  281. //
  282. // then the length of s' can be computed by:
  283. //
  284. // |s'| = |s| # DIFF(xi,y).
  285. //
  286. // Thus, if # is + then DIFF(xi,y) is (yi-x).  For the L_infinity
  287. // norm we make use of the fact that in the program this function
  288. // is only invoked when y > xi, and hence DIFF(xi,y)=y.
  289. //
  290. // Finally, for approximate nearest neighbor queries we assume
  291. // that POW and ROOT are related such that
  292. //
  293. // v*ROOT(x) = ROOT(POW(v)*x)
  294. //
  295. // Here are the values for the various Minkowski norms:
  296. //
  297. // L_p: p even: p odd:
  298. // ------------------------- ------------------------
  299. // POW(v) = v^p POW(v) = |v|^p
  300. // ROOT(x) = x^(1/p) ROOT(x) = x^(1/p)
  301. // # = + # = +
  302. // DIFF(x,y) = y - x DIFF(x,y) = y - x 
  303. //
  304. // L_inf:
  305. // POW(v) = |v|
  306. // ROOT(x) = x
  307. // # = max
  308. // DIFF(x,y) = y
  309. //
  310. // By default the Euclidean norm is assumed.  To change the norm,
  311. // uncomment the appropriate set of macros below.
  312. //----------------------------------------------------------------------
  313. //----------------------------------------------------------------------
  314. // Use the following for the Euclidean norm
  315. //----------------------------------------------------------------------
  316. #define ANN_POW(v) ((v)*(v))
  317. #define ANN_ROOT(x) sqrt(x)
  318. #define ANN_SUM(x,y) ((x) + (y))
  319. #define ANN_DIFF(x,y) ((y) - (x))
  320. //----------------------------------------------------------------------
  321. // Use the following for the L_1 (Manhattan) norm
  322. //----------------------------------------------------------------------
  323. // #define ANN_POW(v) fabs(v)
  324. // #define ANN_ROOT(x) (x)
  325. // #define ANN_SUM(x,y) ((x) + (y))
  326. // #define ANN_DIFF(x,y) ((y) - (x))
  327. //----------------------------------------------------------------------
  328. // Use the following for a general L_p norm
  329. //----------------------------------------------------------------------
  330. // #define ANN_POW(v) pow(fabs(v),p)
  331. // #define ANN_ROOT(x) pow(fabs(x),1/p)
  332. // #define ANN_SUM(x,y) ((x) + (y))
  333. // #define ANN_DIFF(x,y) ((y) - (x))
  334. //----------------------------------------------------------------------
  335. // Use the following for the L_infinity (Max) norm
  336. //----------------------------------------------------------------------
  337. // #define ANN_POW(v) fabs(v)
  338. // #define ANN_ROOT(x) (x)
  339. // #define ANN_SUM(x,y) ((x) > (y) ? (x) : (y))
  340. // #define ANN_DIFF(x,y) (y)
  341. //----------------------------------------------------------------------
  342. // Array types
  343. // The following array types are of basic interest.  A point is
  344. // just a dimensionless array of coordinates, a point array is a
  345. // dimensionless array of points.  A distance array is a
  346. // dimensionless array of distances and an index array is a
  347. // dimensionless array of point indices.  The latter two are used
  348. // when returning the results of k-nearest neighbor queries.
  349. //----------------------------------------------------------------------
  350. typedef ANNcoord* ANNpoint; // a point
  351. typedef ANNpoint* ANNpointArray; // an array of points 
  352. typedef ANNdist*  ANNdistArray; // an array of distances 
  353. typedef ANNidx*   ANNidxArray; // an array of point indices
  354. //----------------------------------------------------------------------
  355. // Basic point and array utilities:
  356. // The following procedures are useful supplements to ANN's nearest
  357. // neighbor capabilities.
  358. //
  359. // annDist():
  360. // Computes the (squared) distance between a pair of points.
  361. // Note that this routine is not used internally by ANN for
  362. // computing distance calculations.  For reasons of efficiency
  363. // this is done using incremental distance calculation.  Thus,
  364. // this routine cannot be modified as a method of changing the
  365. // metric.
  366. //
  367. // Because points (somewhat like strings in C) are stored as
  368. // pointers.  Consequently, creating and destroying copies of
  369. // points may require storage allocation.  These procedures do
  370. // this.
  371. //
  372. // annAllocPt() and annDeallocPt():
  373. // Allocate a deallocate storage for a single point, and
  374. // return a pointer to it.  The argument to AllocPt() is
  375. // used to initialize all components.
  376. //
  377. // annAllocPts() and annDeallocPts():
  378. // Allocate and deallocate an array of points as well a
  379. // place to store their coordinates, and initializes the
  380. // points to point to their respective coordinates.  It
  381. // allocates point storage in a contiguous block large
  382. // enough to store all the points.  It performs no
  383. // initialization.
  384. //
  385. // annCopyPt():
  386. // Creates a copy of a given point, allocating space for
  387. // the new point.  It returns a pointer to the newly
  388. // allocated copy.
  389. //----------------------------------------------------------------------
  390.    
  391. DLL_API ANNdist annDist(
  392. int dim, // dimension of space
  393. ANNpoint p, // points
  394. ANNpoint q);
  395. DLL_API ANNpoint annAllocPt(
  396. int dim, // dimension
  397. ANNcoord c = 0); // coordinate value (all equal)
  398. DLL_API ANNpointArray annAllocPts(
  399. int n, // number of points
  400. int dim); // dimension
  401. DLL_API void annDeallocPt(
  402. ANNpoint &p); // deallocate 1 point
  403.    
  404. DLL_API void annDeallocPts(
  405. ANNpointArray &pa); // point array
  406. DLL_API ANNpoint annCopyPt(
  407. int dim, // dimension
  408. ANNpoint source); // point to copy
  409. //----------------------------------------------------------------------
  410. //Overall structure: ANN supports a number of different data structures
  411. //for approximate and exact nearest neighbor searching.  These are:
  412. //
  413. // ANNbruteForce A simple brute-force search structure.
  414. // ANNkd_tree A kd-tree tree search structure.  ANNbd_tree
  415. // A bd-tree tree search structure (a kd-tree with shrink
  416. // capabilities).
  417. //
  418. // At a minimum, each of these data structures support k-nearest
  419. // neighbor queries.  The nearest neighbor query, annkSearch,
  420. // returns an integer identifier and the distance to the nearest
  421. // neighbor(s) and annRangeSearch returns the nearest points that
  422. // lie within a given query ball.
  423. //
  424. // Each structure is built by invoking the appropriate constructor
  425. // and passing it (at a minimum) the array of points, the total
  426. // number of points and the dimension of the space.  Each structure
  427. // is also assumed to support a destructor and member functions
  428. // that return basic information about the point set.
  429. //
  430. // Note that the array of points is not copied by the data
  431. // structure (for reasons of space efficiency), and it is assumed
  432. // to be constant throughout the lifetime of the search structure.
  433. //
  434. // The search algorithm, annkSearch, is given the query point (q),
  435. // and the desired number of nearest neighbors to report (k), and
  436. // the error bound (eps) (whose default value is 0, implying exact
  437. // nearest neighbors).  It returns two arrays which are assumed to
  438. // contain at least k elements: one (nn_idx) contains the indices
  439. // (within the point array) of the nearest neighbors and the other
  440. // (dd) contains the squared distances to these nearest neighbors.
  441. //
  442. // The search algorithm, annkFRSearch, is a fixed-radius kNN
  443. // search.  In addition to a query point, it is given a (squared)
  444. // radius bound.  (This is done for consistency, because the search
  445. // returns distances as squared quantities.) It does two things.
  446. // First, it computes the k nearest neighbors within the radius
  447. // bound, and second, it returns the total number of points lying
  448. // within the radius bound. It is permitted to set k = 0, in which
  449. // case it effectively answers a range counting query.  If the
  450. // error bound epsilon is positive, then the search is approximate
  451. // in the sense that it is free to ignore any point that lies
  452. // outside a ball of radius r/(1+epsilon), where r is the given
  453. // (unsquared) radius bound.
  454. //
  455. // The generic object from which all the search structures are
  456. // dervied is given below.  It is a virtual object, and is useless
  457. // by itself.
  458. //----------------------------------------------------------------------
  459. class DLL_API ANNpointSet {
  460. public:
  461. virtual ~ANNpointSet() {} // virtual distructor
  462. virtual void annkSearch( // approx k near neighbor search
  463. ANNpoint q, // query point
  464. int k, // number of near neighbors to return
  465. ANNidxArray nn_idx, // nearest neighbor array (modified)
  466. ANNdistArray dd, // dist to near neighbors (modified)
  467. double eps=0.0 // error bound
  468. ) = 0; // pure virtual (defined elsewhere)
  469. virtual int annkFRSearch( // approx fixed-radius kNN search
  470. ANNpoint q, // query point
  471. ANNdist sqRad, // squared radius
  472. int k = 0, // number of near neighbors to return
  473. ANNidxArray nn_idx = NULL, // nearest neighbor array (modified)
  474. ANNdistArray dd = NULL, // dist to near neighbors (modified)
  475. double eps=0.0 // error bound
  476. ) = 0; // pure virtual (defined elsewhere)
  477. virtual int theDim() = 0; // return dimension of space
  478. virtual int nPoints() = 0; // return number of points
  479. // return pointer to points
  480. virtual ANNpointArray thePoints() = 0;
  481. };
  482. //----------------------------------------------------------------------
  483. // Brute-force nearest neighbor search:
  484. // The brute-force search structure is very simple but inefficient.
  485. // It has been provided primarily for the sake of comparison with
  486. // and validation of the more complex search structures.
  487. //
  488. // Query processing is the same as described above, but the value
  489. // of epsilon is ignored, since all distance calculations are
  490. // performed exactly.
  491. //
  492. // WARNING: This data structure is very slow, and should not be
  493. // used unless the number of points is very small.
  494. //
  495. // Internal information:
  496. // ---------------------
  497. // This data structure bascially consists of the array of points
  498. // (each a pointer to an array of coordinates).  The search is
  499. // performed by a simple linear scan of all the points.
  500. //----------------------------------------------------------------------
  501. class DLL_API ANNbruteForce: public ANNpointSet {
  502. int dim; // dimension
  503. int n_pts; // number of points
  504. ANNpointArray pts; // point array
  505. public:
  506. ANNbruteForce( // constructor from point array
  507. ANNpointArray pa, // point array
  508. int n, // number of points
  509. int dd); // dimension
  510. ~ANNbruteForce(); // destructor
  511. void annkSearch( // approx k near neighbor search
  512. ANNpoint q, // query point
  513. int k, // number of near neighbors to return
  514. ANNidxArray nn_idx, // nearest neighbor array (modified)
  515. ANNdistArray dd, // dist to near neighbors (modified)
  516. double eps=0.0); // error bound
  517. int annkFRSearch( // approx fixed-radius kNN search
  518. ANNpoint q, // query point
  519. ANNdist sqRad, // squared radius
  520. int k = 0, // number of near neighbors to return
  521. ANNidxArray nn_idx = NULL, // nearest neighbor array (modified)
  522. ANNdistArray dd = NULL, // dist to near neighbors (modified)
  523. double eps=0.0); // error bound
  524. int theDim() // return dimension of space
  525. { return dim; }
  526. int nPoints() // return number of points
  527. { return n_pts; }
  528. ANNpointArray thePoints() // return pointer to points
  529. {  return pts;  }
  530. };
  531. //----------------------------------------------------------------------
  532. // kd- and bd-tree splitting and shrinking rules
  533. // kd-trees supports a collection of different splitting rules.
  534. // In addition to the standard kd-tree splitting rule proposed
  535. // by Friedman, Bentley, and Finkel, we have introduced a
  536. // number of other splitting rules, which seem to perform
  537. // as well or better (for the distributions we have tested).
  538. //
  539. // The splitting methods given below allow the user to tailor
  540. // the data structure to the particular data set.  They are
  541. // are described in greater details in the kd_split.cc source
  542. // file.  The method ANN_KD_SUGGEST is the method chosen (rather
  543. // subjectively) by the implementors as the one giving the
  544. // fastest performance, and is the default splitting method.
  545. //
  546. // As with splitting rules, there are a number of different
  547. // shrinking rules.  The shrinking rule ANN_BD_NONE does no
  548. // shrinking (and hence produces a kd-tree tree).  The rule
  549. // ANN_BD_SUGGEST uses the implementors favorite rule.
  550. //----------------------------------------------------------------------
  551. enum ANNsplitRule {
  552. ANN_KD_STD = 0, // the optimized kd-splitting rule
  553. ANN_KD_MIDPT = 1, // midpoint split
  554. ANN_KD_FAIR = 2, // fair split
  555. ANN_KD_SL_MIDPT = 3, // sliding midpoint splitting method
  556. ANN_KD_SL_FAIR = 4, // sliding fair split method
  557. ANN_KD_SUGGEST = 5}; // the authors' suggestion for best
  558. const int ANN_N_SPLIT_RULES = 6; // number of split rules
  559. enum ANNshrinkRule {
  560. ANN_BD_NONE = 0, // no shrinking at all (just kd-tree)
  561. ANN_BD_SIMPLE = 1, // simple splitting
  562. ANN_BD_CENTROID = 2, // centroid splitting
  563. ANN_BD_SUGGEST = 3}; // the authors' suggested choice
  564. const int ANN_N_SHRINK_RULES = 4; // number of shrink rules
  565. //----------------------------------------------------------------------
  566. // kd-tree:
  567. // The main search data structure supported by ANN is a kd-tree.
  568. // The main constructor is given a set of points and a choice of
  569. // splitting method to use in building the tree.
  570. //
  571. // Construction:
  572. // -------------
  573. // The constructor is given the point array, number of points,
  574. // dimension, bucket size (default = 1), and the splitting rule
  575. // (default = ANN_KD_SUGGEST).  The point array is not copied, and
  576. // is assumed to be kept constant throughout the lifetime of the
  577. // search structure.  There is also a "load" constructor that
  578. // builds a tree from a file description that was created by the
  579. // Dump operation.
  580. //
  581. // Search:
  582. // -------
  583. // There are two search methods:
  584. //
  585. // Standard search (annkSearch()):
  586. // Searches nodes in tree-traversal order, always visiting
  587. // the closer child first.
  588. // Priority search (annkPriSearch()):
  589. // Searches nodes in order of increasing distance of the
  590. // associated cell from the query point.  For many
  591. // distributions the standard search seems to work just
  592. // fine, but priority search is safer for worst-case
  593. // performance.
  594. //
  595. // Printing:
  596. // ---------
  597. // There are two methods provided for printing the tree.  Print()
  598. // is used to produce a "human-readable" display of the tree, with
  599. // indenation, which is handy for debugging.  Dump() produces a
  600. // format that is suitable reading by another program.  There is a
  601. // "load" constructor, which constructs a tree which is assumed to
  602. // have been saved by the Dump() procedure.
  603. //
  604. // Performance and Structure Statistics:
  605. // -------------------------------------
  606. // The procedure getStats() collects statistics information on the
  607. // tree (its size, height, etc.)  See ANNperf.h for information on
  608. // the stats structure it returns.
  609. //
  610. // Internal information:
  611. // ---------------------
  612. // The data structure consists of three major chunks of storage.
  613. // The first (implicit) storage are the points themselves (pts),
  614. // which have been provided by the users as an argument to the
  615. // constructor, or are allocated dynamically if the tree is built
  616. // using the load constructor).  These should not be changed during
  617. // the lifetime of the search structure.  It is the user's
  618. // responsibility to delete these after the tree is destroyed.
  619. //
  620. // The second is the tree itself (which is dynamically allocated in
  621. // the constructor) and is given as a pointer to its root node
  622. // (root).  These nodes are automatically deallocated when the tree
  623. // is deleted.  See the file src/kd_tree.h for further information
  624. // on the structure of the tree nodes.
  625. //
  626. // Each leaf of the tree does not contain a pointer directly to a
  627. // point, but rather contains a pointer to a "bucket", which is an
  628. // array consisting of point indices.  The third major chunk of
  629. // storage is an array (pidx), which is a large array in which all
  630. // these bucket subarrays reside.  (The reason for storing them
  631. // separately is the buckets are typically small, but of varying
  632. // sizes.  This was done to avoid fragmentation.)  This array is
  633. // also deallocated when the tree is deleted.
  634. //
  635. // In addition to this, the tree consists of a number of other
  636. // pieces of information which are used in searching and for
  637. // subsequent tree operations.  These consist of the following:
  638. //
  639. // dim Dimension of space
  640. // n_pts Number of points currently in the tree
  641. // n_max Maximum number of points that are allowed
  642. // in the tree
  643. // bkt_size Maximum bucket size (no. of points per leaf)
  644. // bnd_box_lo Bounding box low point
  645. // bnd_box_hi Bounding box high point
  646. // splitRule Splitting method used
  647. //
  648. //----------------------------------------------------------------------
  649. //----------------------------------------------------------------------
  650. // Some types and objects used by kd-tree functions
  651. // See src/kd_tree.h and src/kd_tree.cpp for definitions
  652. //----------------------------------------------------------------------
  653. class ANNkdStats; // stats on kd-tree
  654. class ANNkd_node; // generic node in a kd-tree
  655. typedef ANNkd_node* ANNkd_ptr; // pointer to a kd-tree node
  656. class DLL_API ANNkd_tree: public ANNpointSet {
  657. protected:
  658. int dim; // dimension of space
  659. int n_pts; // number of points in tree
  660. int bkt_size; // bucket size
  661. ANNpointArray pts; // the points
  662. ANNidxArray pidx; // point indices (to pts array)
  663. ANNkd_ptr root; // root of kd-tree
  664. ANNpoint bnd_box_lo; // bounding box low point
  665. ANNpoint bnd_box_hi; // bounding box high point
  666. void SkeletonTree( // construct skeleton tree
  667. int n, // number of points
  668. int dd, // dimension
  669. int bs, // bucket size
  670. ANNpointArray pa = NULL, // point array (optional)
  671. ANNidxArray pi = NULL); // point indices (optional)
  672. public:
  673. ANNkd_tree( // build skeleton tree
  674. int n = 0, // number of points
  675. int dd = 0, // dimension
  676. int bs = 1); // bucket size
  677. ANNkd_tree( // build from point array
  678. ANNpointArray pa, // point array
  679. int n, // number of points
  680. int dd, // dimension
  681. int bs = 1, // bucket size
  682. ANNsplitRule split = ANN_KD_SUGGEST); // splitting method
  683. ANNkd_tree( // build from dump file
  684. std::istream& in); // input stream for dump file
  685. ~ANNkd_tree(); // tree destructor
  686. void annkSearch( // approx k near neighbor search
  687. ANNpoint q, // query point
  688. int k, // number of near neighbors to return
  689. ANNidxArray nn_idx, // nearest neighbor array (modified)
  690. ANNdistArray dd, // dist to near neighbors (modified)
  691. double eps=0.0); // error bound
  692. void annkPriSearch(  // priority k near neighbor search
  693. ANNpoint q, // query point
  694. int k, // number of near neighbors to return
  695. ANNidxArray nn_idx, // nearest neighbor array (modified)
  696. ANNdistArray dd, // dist to near neighbors (modified)
  697. double eps=0.0); // error bound
  698. int annkFRSearch( // approx fixed-radius kNN search
  699. ANNpoint q, // the query point
  700. ANNdist sqRad, // squared radius of query ball
  701. int k, // number of neighbors to return
  702. ANNidxArray nn_idx = NULL, // nearest neighbor array (modified)
  703. ANNdistArray dd = NULL, // dist to near neighbors (modified)
  704. double eps=0.0); // error bound
  705. int theDim() // return dimension of space
  706. { return dim; }
  707. int nPoints() // return number of points
  708. { return n_pts; }
  709. ANNpointArray thePoints() // return pointer to points
  710. {  return pts;  }
  711. virtual void Print( // print the tree (for debugging)
  712. ANNbool with_pts, // print points as well?
  713. std::ostream& out); // output stream
  714. virtual void Dump( // dump entire tree
  715. ANNbool with_pts, // print points as well?
  716. std::ostream& out); // output stream
  717. virtual void getStats( // compute tree statistics
  718. ANNkdStats& st); // the statistics (modified)
  719. };
  720. //----------------------------------------------------------------------
  721. // Box decomposition tree (bd-tree)
  722. // The bd-tree is inherited from a kd-tree.  The main difference
  723. // in the bd-tree and the kd-tree is a new type of internal node
  724. // called a shrinking node (in the kd-tree there is only one type
  725. // of internal node, a splitting node).  The shrinking node
  726. // makes it possible to generate balanced trees in which the
  727. // cells have bounded aspect ratio, by allowing the decomposition
  728. // to zoom in on regions of dense point concentration.  Although
  729. // this is a nice idea in theory, few point distributions are so
  730. // densely clustered that this is really needed.
  731. //----------------------------------------------------------------------
  732. class DLL_API ANNbd_tree: public ANNkd_tree {
  733. public:
  734. ANNbd_tree( // build skeleton tree
  735. int n, // number of points
  736. int dd, // dimension
  737. int bs = 1) // bucket size
  738. : ANNkd_tree(n, dd, bs) {} // build base kd-tree
  739. ANNbd_tree( // build from point array
  740. ANNpointArray pa, // point array
  741. int n, // number of points
  742. int dd, // dimension
  743. int bs = 1, // bucket size
  744. ANNsplitRule split  = ANN_KD_SUGGEST, // splitting rule
  745. ANNshrinkRule shrink = ANN_BD_SUGGEST); // shrinking rule
  746. ANNbd_tree( // build from dump file
  747. std::istream& in); // input stream for dump file
  748. };
  749. //----------------------------------------------------------------------
  750. // Other functions
  751. // annMaxPtsVisit Sets a limit on the maximum number of points
  752. // to visit in the search.
  753. //  annClose Can be called when all use of ANN is finished.
  754. // It clears up a minor memory leak.
  755. //----------------------------------------------------------------------
  756. DLL_API void annMaxPtsVisit( // max. pts to visit in search
  757. int maxPts); // the limit
  758. DLL_API void annClose(); // called to end use of ANN
  759. #endif