Jafar
|
00001 /* $Id$ */ 00002 00003 #ifndef SAMS_KDTREE_HPP 00004 #define SAMS_KDTREE_HPP 00005 00006 // 00007 // (c) Matthew B. Kennel, Institute for Nonlinear Science, UCSD (2004) 00008 // 00009 // Licensed under the Academic Free License version 1.1 found at the end of this file 00010 00011 // 00012 // Modified by Maxime Cottret 00013 // 00014 00015 // 00016 // Implement a kd tree for fast searching of points in a fixed data base 00017 // in k-dimensional Euclidean space. 00018 // 00019 // 00020 00021 #include <vector> 00022 #include <algorithm> 00023 #include "jmath/jblas.hpp" 00024 00025 using namespace std; 00026 00027 namespace jafar { 00028 namespace sams { 00029 00030 typedef struct { 00031 double lower, upper; 00032 } interval; 00033 00034 00035 // let the compiler know that this is a names of classes. 00036 class Kdtree_node; 00037 class searchrecord; 00038 00039 // 00040 // struct KDTREE_RESULT 00041 // class KDTREE_RESULT 00042 // 00043 00048 struct Kdtree_result { 00049 // 00050 // the search routines return a (wrapped) vector 00051 // of these. 00052 // 00053 public: 00054 double dis; 00055 int idx; 00056 00057 00058 bool operator<(const Kdtree_result& e1) const{ 00059 return (dis < e1.dis); 00060 } 00061 00062 }; 00063 00064 00069 class Kdtree_result_vector : public vector<Kdtree_result> { 00070 // inherit a vector<Kdtree_result> 00071 // but, optionally maintain it in heap form as a priority 00072 // queue. 00073 public: 00074 00075 00082 void push_element_and_heapify(Kdtree_result& e); 00083 double replace_maxpri_elt_return_new_maxpri(Kdtree_result& e); 00084 00085 00090 double max_value(); 00091 00092 }; 00093 00094 00099 class Kdtree { 00100 public: 00109 const jblas::mat& the_data; 00110 00112 const int N; 00114 int dim; 00116 bool sort_results; 00118 const bool rearrange; 00119 00120 public: 00121 00128 Kdtree(jblas::mat& data_in,bool sort_out = true, bool rearrange_in = true,int dim_in=-1); 00129 00131 ~Kdtree(); 00132 00133 00134 public: 00135 // search routines 00136 00140 void n_nearest_brute_force(jblas::vec& qv, int nn, Kdtree_result_vector& result); 00141 00143 void n_nearest(jblas::vec& qv, int nn, Kdtree_result_vector& result); 00144 00148 void n_nearest_around_point(int idxin, int correltime, int nn, 00149 Kdtree_result_vector& result); 00150 00154 void r_nearest(jblas::vec& qv, double r2,Kdtree_result_vector& result); 00155 00159 void r_nearest_around_point(int idxin, int correltime, double r2, 00160 Kdtree_result_vector& result); 00161 00163 int r_count(jblas::vec& qv, double r2); 00164 00166 int r_count_around_point(int idxin, int correltime, double r2); 00167 00168 00169 friend class Kdtree_node; 00170 friend class searchrecord; 00171 private: 00172 // private data members 00173 00174 Kdtree_node* root; // the root pointer 00175 00176 const jblas::mat* data; 00177 // pointing either to the_data or an internal 00178 // rearranged data as necessary 00179 00180 vector<int> ind; 00181 // the index for the tree leaves. Data in a leaf with bounds [l,u] are 00182 // in 'the_data[ind[l],*] to the_data[ind[u],*] 00183 00184 jblas::mat rearranged_data; 00185 // if rearrange is true then this is the rearranged data storage. 00186 00187 00188 static const int bucketsize = 12; // global constant. 00189 00190 private: 00191 void set_data(jblas::mat& din); 00192 void build_tree(); // builds the tree. Used upon construction. 00193 Kdtree_node* build_tree_for_range(int l, int u, Kdtree_node* parent); 00194 void select_on_coordinate(int c, int k, int l, int u); 00195 int select_on_coordinate_value(int c, double alpha, int l, int u); 00196 void spread_in_coordinate(int c, int l, int u, interval& interv); 00197 }; 00198 00199 #ifndef SWIG 00200 00201 // 00202 // search record substructure 00203 // 00204 // one of these is created for each search. 00205 // this holds useful information to be used 00206 // during the search 00207 00208 00209 00210 static const double infinity = 1.0e38; 00211 00212 class searchrecord { 00213 00214 private: 00215 friend class Kdtree; 00216 friend class Kdtree_node; 00217 00218 jblas::vec& qv; 00219 int dim; 00220 bool rearrange; 00221 unsigned int nn; // , nfound; 00222 double ballsize; 00223 int centeridx, correltime; 00224 00225 Kdtree_result_vector& result; // results 00226 const jblas::mat* data; 00227 const vector<int>& ind; 00228 // constructor 00229 00230 public: 00231 searchrecord(jblas::vec& qv_in, Kdtree& tree_in, 00232 Kdtree_result_vector& result_in) : 00233 qv(qv_in), 00234 result(result_in), 00235 data(tree_in.data), 00236 ind(tree_in.ind) 00237 { 00238 dim = tree_in.dim; 00239 rearrange = tree_in.rearrange; 00240 ballsize = infinity; 00241 nn = 0; 00242 }; 00243 00244 }; 00245 00246 00247 00248 // 00249 // class KDTREE_NODE 00250 // 00251 // a node in the tree. Many are created per tree dynamically.. 00252 // 00253 00254 00255 class Kdtree_node { 00256 public: 00257 // constructor 00258 Kdtree_node(int dim); 00259 //, int cut_dim_in, 00260 // double cut_val_in, double cut_val_left_in, 00261 // double cut_val_right_in); 00262 // destructor 00263 ~Kdtree_node(); 00264 00265 private: 00266 // visible to self and Kdtree. 00267 friend class Kdtree; // allow Kdtree to access private 00268 00269 int cut_dim; // dimension to cut; 00270 double cut_val, cut_val_left, cut_val_right; //cut value 00271 int l,u; // extents in index array for searching 00272 00273 vector<interval> box; // [min,max] of the box enclosing all points 00274 00275 Kdtree_node *left, *right; // pointers to left and right nodes. 00276 00277 void search(searchrecord& sr); 00278 // recursive innermost core routine for searching.. 00279 00280 bool box_in_search_range(searchrecord& sr); 00281 // return true if the bounding box for this node is within the 00282 // search range given by the searchvector and maximum ballsize in 'sr'. 00283 00284 void check_query_in_bound(searchrecord& sr); // debugging only 00285 00286 // for processing final buckets. 00287 void process_terminal_node(searchrecord& sr); 00288 void process_terminal_node_fixedball(searchrecord& sr); 00289 00290 00291 }; 00292 00293 #endif // SWIG 00294 00295 } // namespace sams 00296 } // namespace jafar 00297 00298 #endif // SAMS_KDTREE_HPP 00299 00300 00301 // The KDTREE2 software is licensed under the terms of the Academic Free 00302 // Software License, listed herein. In addition, users of this software 00303 // must give appropriate citation in relevant technical documentation or 00304 // journal paper to the author, Matthew B. Kennel, Institute For 00305 // Nonlinear Science, preferably via a reference to the www.arxiv.org 00306 // repository of this document, {\tt www.arxiv.org e-print: 00307 // physics/0408067}. This requirement will be deemed to be advisory and 00308 // not mandatory as is necessary to permit the free inclusion of the 00309 // present software with any software licensed under the terms of any 00310 // version of the GNU General Public License, or GNU Library General 00311 // Public License. 00312 00313 00314 // Academic Free License 00315 // Version 1.1 00316 00317 // This Academic Free License applies to any original work of authorship 00318 // (the "Original Work") whose owner (the "Licensor") has placed the 00319 // following notice immediately following the copyright notice for the 00320 // Original Work: "Licensed under the Academic Free License version 1.1." 00321 00322 // Grant of License. Licensor hereby grants to any person obtaining a 00323 // copy of the Original Work ("You") a world-wide, royalty-free, 00324 // non-exclusive, perpetual, non-sublicenseable license (1) to use, copy, 00325 // modify, merge, publish, perform, distribute and/or sell copies of the 00326 // Original Work and derivative works thereof, and (2) under patent 00327 // claims owned or controlled by the Licensor that are embodied in the 00328 // Original Work as furnished by the Licensor, to make, use, sell and 00329 // offer for sale the Original Work and derivative works thereof, subject 00330 // to the following conditions. 00331 00332 // Right of Attribution. Redistributions of the Original Work must 00333 // reproduce all copyright notices in the Original Work as furnished by 00334 // the Licensor, both in the Original Work itself and in any 00335 // documentation and/or other materials provided with the distribution of 00336 // the Original Work in executable form. 00337 00338 // Exclusions from License Grant. Neither the names of Licensor, nor the 00339 // names of any contributors to the Original Work, nor any of their 00340 // trademarks or service marks, may be used to endorse or promote 00341 // products derived from this Original Work without express prior written 00342 // permission of the Licensor. 00343 00344 // WARRANTY AND DISCLAIMERS. LICENSOR WARRANTS THAT THE COPYRIGHT IN AND 00345 // TO THE ORIGINAL WORK IS OWNED BY THE LICENSOR OR THAT THE ORIGINAL 00346 // WORK IS DISTRIBUTED BY LICENSOR UNDER A VALID CURRENT LICENSE FROM THE 00347 // COPYRIGHT OWNER. EXCEPT AS EXPRESSLY STATED IN THE IMMEDIATELY 00348 // PRECEEDING SENTENCE, THE ORIGINAL WORK IS PROVIDED UNDER THIS LICENSE 00349 // ON AN "AS IS" BASIS, WITHOUT WARRANTY, EITHER EXPRESS OR IMPLIED, 00350 // INCLUDING, WITHOUT LIMITATION, THE WARRANTY OF NON-INFRINGEMENT AND 00351 // WARRANTIES THAT THE ORIGINAL WORK IS MERCHANTABLE OR FIT FOR A 00352 // PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL 00353 // WORK IS WITH YOU. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL 00354 // PART OF THIS LICENSE. NO LICENSE TO ORIGINAL WORK IS GRANTED HEREUNDER 00355 // EXCEPT UNDER THIS DISCLAIMER. 00356 00357 // LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL 00358 // THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, 00359 // SHALL THE LICENSOR BE LIABLE TO ANY PERSON FOR ANY DIRECT, INDIRECT, 00360 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING 00361 // AS A RESULT OF THIS LICENSE OR THE USE OF THE ORIGINAL WORK INCLUDING, 00362 // WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, 00363 // COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL 00364 // DAMAGES OR LOSSES, EVEN IF SUCH PERSON SHALL HAVE BEEN INFORMED OF THE 00365 // POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT 00366 // APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH 00367 // PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH 00368 // LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR 00369 // LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION 00370 // AND LIMITATION MAY NOT APPLY TO YOU. 00371 00372 // License to Source Code. The term "Source Code" means the preferred 00373 // form of the Original Work for making modifications to it and all 00374 // available documentation describing how to access and modify the 00375 // Original Work. Licensor hereby agrees to provide a machine-readable 00376 // copy of the Source Code of the Original Work along with each copy of 00377 // the Original Work that Licensor distributes. Licensor reserves the 00378 // right to satisfy this obligation by placing a machine-readable copy of 00379 // the Source Code in an information repository reasonably calculated to 00380 // permit inexpensive and convenient access by You for as long as 00381 // Licensor continues to distribute the Original Work, and by publishing 00382 // the address of that information repository in a notice immediately 00383 // following the copyright notice that applies to the Original Work. 00384 00385 // Mutual Termination for Patent Action. This License shall terminate 00386 // automatically and You may no longer exercise any of the rights granted 00387 // to You by this License if You file a lawsuit in any court alleging 00388 // that any OSI Certified open source software that is licensed under any 00389 // license containing this "Mutual Termination for Patent Action" clause 00390 // infringes any patent claims that are essential to use that software. 00391 00392 // This license is Copyright (C) 2002 Lawrence E. Rosen. All rights 00393 // reserved. Permission is hereby granted to copy and distribute this 00394 // license without modification. This license may not be modified without 00395 // the express written permission of its copyright owner. 00396 00397
Generated on Wed Oct 15 2014 00:37:27 for Jafar by doxygen 1.7.6.1 |