Loading...
Searching...
No Matches
KdTree.tpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25// ========================================================================== //
26// - SORTING ALGORITHMS - //
27// //
28// Functions for data sorting. //
29// ========================================================================== //
30// INFO //
31// Author : Alessandro Alaia //
32// Version : v2.0 //
33// //
34// All rights reserved. //
35// ========================================================================== //
36
37namespace bitpit{
38
57// ========================================================================== //
58// TEMPLATE IMPLEMENTATIONS FOR KDNODE //
59// ========================================================================== //
60
61// Constructor(s) =========================================================== //
62
63// -------------------------------------------------------------------------- //
68template<class T, class T1>
70 void
71) {
72
73// ========================================================================== //
74// VARIABLES DECLARATION //
75// ========================================================================== //
76
77// Local variables
78// none
79
80// Counters
81// none
82
83// ========================================================================== //
84// SET DEFAULT VALUES //
85// ========================================================================== //
86reset();
87
88return; }
89
90// Methods ================================================================== //
91
92// -------------------------------------------------------------------------- //
97template<class T, class T1>
99 void
100) {
101
102// ========================================================================== //
103// VARIABLES DECLARATION //
104// ========================================================================== //
105
106// Local variables
107// none
108
109// Counters
110// none
111
112// ========================================================================== //
113// SET DEFAULT VALUES //
114// ========================================================================== //
115lchild_ = -1;
116rchild_ = -1;
117
118object_ = nullptr;
119
120label = T1();
121
122return; }
123
124// ========================================================================== //
125// TEMPLATE IMPLEMENTATIONS FOR KDTREE //
126// ========================================================================== //
127
150// Constructors ============================================================= //
151
152// -------------------------------------------------------------------------- //
161template<int d, class T, class T1>
163 int maxstack
164) {
165
166// ========================================================================== //
167// VARIABLES DECLARATION //
168// ========================================================================== //
169
170// Local variables
171// none
172
173// Counters
174// none
175
176// ========================================================================== //
177// SET DEFAULT VALUES //
178// ========================================================================== //
179MAXSTK = maxstack;
180n_nodes = 0;
181
182// ========================================================================== //
183// RESIZE NODE LIST //
184// ========================================================================== //
185increaseStack();
186
187return; }
188
189// Methods ================================================================== //
190
191// -------------------------------------------------------------------------- //
195template<int d, class T, class T1>
197 void
198 ) {
199
200 // ========================================================================== //
201 // VARIABLES DECLARATION //
202 // ========================================================================== //
203
204 // Local variables
205 // none
206
207 // Counters
208 // none
209
210 // ========================================================================== //
211 // CLEAR CONTENT //
212 // ========================================================================== //
213 for (int i = 0; i < n_nodes; ++i) {
214 nodes[i].reset();
215 }
216
217 n_nodes = 0;
218
219 return;
220}
221
222// -------------------------------------------------------------------------- //
234template<int d, class T, class T1>
236 const T *P_
237) {
238
239// ========================================================================== //
240// VARIABLES DECLARATION //
241// ========================================================================== //
242
243// Local variables
244bool check = false;
245int index = -1;
246int prev_ = -1, next_ = 0;
247int lev = 0, dim;
248
249// Counters
250// none
251
252// ========================================================================== //
253// EXIT FOR EMPTY TREE //
254// ========================================================================== //
255if (n_nodes == 0) { return(index); };
256
257// ========================================================================== //
258// MOVE ON TREE BRANCHES //
259// ========================================================================== //
260
261// Find node on leaf -------------------------------------------------------- //
262while ((next_ >= 0) && (!check)) {
263 check = ((*P_) == (*(nodes[next_].object_)));
264 prev_ = next_;
265 dim = lev % d;
266 if ((*P_)[dim] <= (*(nodes[next_].object_))[dim]) {
267 next_ = nodes[next_].lchild_;
268 }
269 else {
270 next_ = nodes[next_].rchild_;
271 }
272 lev++;
273} //next
274if (check) {
275 index = prev_;
276}
277
278return(index); };
279
280// -------------------------------------------------------------------------- //
294template<int d, class T, class T1>
296 const T *P_,
297 T1 &label
298) {
299
300// ========================================================================== //
301// VARIABLES DECLARATION //
302// ========================================================================== //
303
304// Local variables
305bool check = false;
306int index = -1;
307int prev_ = -1, next_ = 0;
308int lev = 0, dim;
309
310// Counters
311// none
312
313// ========================================================================== //
314// EXIT FOR EMPTY TREE //
315// ========================================================================== //
316if (n_nodes == 0) { return(index); };
317
318// ========================================================================== //
319// MOVE ON TREE BRANCHES //
320// ========================================================================== //
321
322// Find node on leaf -------------------------------------------------------- //
323while ((next_ >= 0) && (!check)) {
324 check = ((*P_) == (*(nodes[next_].object_)));
325 prev_ = next_;
326 dim = lev % d;
327 if ((*P_)[dim] <= (*(nodes[next_].object_))[dim]) {
328 next_ = nodes[next_].lchild_;
329 }
330 else {
331 next_ = nodes[next_].rchild_;
332 }
333 lev++;
334} //next
335if (check) {
336 index = prev_;
337 label = nodes[prev_].label;
338}
339
340return(index); };
341
342// -------------------------------------------------------------------------- //
359template<int d, class T, class T1 >
360template< class T2>
362 const T *P_,
363 T2 h,
364 bool debug,
365 int next_,
366 int lev
367) {
368
369// ========================================================================== //
370// VARIABLES DECLARATION //
371// ========================================================================== //
372
373// Local variables
374int index_l = -1, index_r = -1;
375int prev_ = next_;
376int dim;
377
378// Counters
379// none
380
381// ========================================================================== //
382// EXIT FOR EMPTY TREE //
383// ========================================================================== //
384if (n_nodes == 0) { return(-1); };
385
386// ========================================================================== //
387// MOVE ON TREE BRANCHES //
388// ========================================================================== //
389
390// Check if root is in the h-neighbor of P_ --------------------------------- //
391//if (debug) { cout << "visiting: " << prev_ << endl; }
392if (distance<T2>(*(nodes[prev_].object_), *P_) <= h) { return(prev_); }
393
394// Move on next branch ------------------------------------------------------ //
395dim = lev % d;
396if (((*(nodes[prev_].object_))[dim] >= (*P_)[dim] - h)
397 && (nodes[prev_].lchild_ >= 0)) {
398// if (nodes[prev_].lchild_ >= 0) {
399 next_ = nodes[prev_].lchild_;
400 index_l = hNeighbor(P_, h, debug, next_, lev+1);
401}
402if (((*(nodes[prev_].object_))[dim] <= (*P_)[dim] + h)
403 && (nodes[prev_].rchild_ >= 0)) {
404// if (nodes[prev_].rchild_ >= 0) {
405 next_ = nodes[prev_].rchild_;
406 index_r = hNeighbor(P_, h, debug, next_, lev+1);
407}
408
409//if (debug) { cout << "result is: " << max(index_l, index_r) << endl; }
410return(std::max(index_l, index_r)); };
411
412// -------------------------------------------------------------------------- //
430template<int d, class T, class T1 >
431template< class T2>
433 const T *P_,
434 T1 &label,
435 T2 h,
436 int next_,
437 int lev
438) {
439
440// ========================================================================== //
441// VARIABLES DECLARATION //
442// ========================================================================== //
443
444// Local variables
445// bool check = false;
446int index_l = -1, index_r = -1;
447// int dim;
448
449// Counters
450// none
451
452// // ========================================================================== //
453// // EXIT FOR EMPTY TREE //
454// // ========================================================================== //
455// if (n_nodes == 0) { return(index); };
456
457// // ========================================================================== //
458// // MOVE ON TREE BRANCHES //
459// // ========================================================================== //
460
461// // Find node on leaf -------------------------------------------------------- //
462// while ((next_ >= 0) && (!check)) {
463 // check = (distance<T2>(*P_, *(nodes[prev_].object_)) <= h);
464 // prev_ = next_;
465 // dim = lev % d;
466 // if ((*P_)[dim] <= (*(nodes[next_].object_))[dim]) {
467 // next_ = nodes[next_].lchild_;
468 // }
469 // else {
470 // next_ = nodes[next_].rchild_;
471 // }
472 // lev++;
473// } //next
474// if (check) {
475 // index = prev_;
476 // label = nodes[prev_].label;
477// }
478
479return(std::max(index_l, index_r)); };
480
481// -------------------------------------------------------------------------- //
487template<int d, class T, class T1>
489 T *P_
490) {
491
492// ========================================================================== //
493// VARIABLES DECLARATION //
494// ========================================================================== //
495
496// Local variables
497bool left;
498int prev_ = -1, next_ = 0;
499int lev = 0, dim;
500
501// Counters
502// none
503
504// ========================================================================== //
505// EXIT CONDITION FOR EMPTY TREE //
506// ========================================================================== //
507if (n_nodes == 0) {
508 nodes[0].object_ = P_;
509 n_nodes++;
510 return;
511};
512
513// ========================================================================== //
514// MOVE ON TREE BRANCHES //
515// ========================================================================== //
516
517// Find node on leaf -------------------------------------------------------- //
518while (next_ >= 0) {
519 prev_ = next_;
520 dim = lev % d;
521 if ((*P_)[dim] <= (*(nodes[next_].object_))[dim]) {
522 next_ = nodes[next_].lchild_;
523 left = true;
524 }
525 else {
526 next_ = nodes[next_].rchild_;
527 left = false;
528 }
529 lev++;
530} //next
531
532// Insert new element ------------------------------------------------------- //
533
534// Increase stack size
535if (n_nodes+1 > nodes.size()) {
536 increaseStack();
537}
538
539// Update parent
540if (left) {
541 nodes[prev_].lchild_ = n_nodes;
542}
543else {
544 nodes[prev_].rchild_ = n_nodes;
545}
546
547// Insert children
548nodes[n_nodes].object_ = P_;
549n_nodes++;
550
551return; };
552
553
554// -------------------------------------------------------------------------- //
561template<int d, class T, class T1>
563 T *P_,
564 T1 &label
565) {
566
567// ========================================================================== //
568// VARIABLES DECLARATION //
569// ========================================================================== //
570
571// Local variables
572bool left;
573int prev_ = -1, next_ = 0;
574int lev = 0, dim;
575
576// Counters
577// none
578
579// ========================================================================== //
580// QUIT FOR EMPTY TREE //
581// ========================================================================== //
582if (n_nodes == 0) {
583 nodes[0].object_ = P_;
584 nodes[0].label = label;
585 n_nodes++;
586 return;
587};
588
589// ========================================================================== //
590// MOVE ON TREE BRANCHES //
591// ========================================================================== //
592
593// Find node on leaf -------------------------------------------------------- //
594while (next_ >= 0) {
595 prev_ = next_;
596 dim = lev % d;
597 if ((*P_)[dim] <= (*(nodes[next_].object_))[dim]) {
598 next_ = nodes[next_].lchild_;
599 left = true;
600 }
601 else {
602 next_ = nodes[next_].rchild_;
603 left = false;
604 }
605 lev++;
606} //next
607
608// Insert new element ------------------------------------------------------- //
609
610// Increase stack size
611if (n_nodes+1 > (long) nodes.size()) {
612 increaseStack();
613}
614
615// Update parent
616if (left) {
617 nodes[prev_].lchild_ = n_nodes;
618}
619else {
620 nodes[prev_].rchild_ = n_nodes;
621}
622
623// Insert children
624nodes[n_nodes].object_ = P_;
625nodes[n_nodes].label = label;
626n_nodes++;
627
628return; };
629
630// -------------------------------------------------------------------------- //
636template<int d, class T, class T1>
638 void
639) {
640
641// ========================================================================== //
642// VARIABLES DECLARATION //
643// ========================================================================== //
644
645// Local variables
646// none
647
648// Counters
649// none
650
651// ========================================================================== //
652// INCREASE STACK SIZE //
653// ========================================================================== //
654nodes.resize(nodes.size() + MAXSTK);
655
656return; };
657
658// -------------------------------------------------------------------------- //
663template<int d, class T, class T1>
664void KdTree<d, T, T1>::decreaseStack(
665 void
666) {
667
668// ========================================================================== //
669// VARIABLES DECLARATION //
670// ========================================================================== //
671
672// Local variables
673// none
674
675// Counters
676// none
677
678// ========================================================================== //
679// INCREASE STACK SIZE //
680// ========================================================================== //
681nodes.resize(max(MAXSTK, nodes.size() - MAXSTK));
682
683return; };
684
685// -------------------------------------------------------------------------- //
693template<int d, class T, class T1 >
694template< class T2>
695T2 KdTree<d, T, T1>::distance(
696 const T &P1,
697 const T &P2
698) const {
699
700// Get the type of the coordinates
701typedef typename std::remove_const<typename std::remove_reference<decltype(std::declval<T>()[0])>::type>::type CoordType;
702
703// Evaluate the ndistance
704std::array<CoordType, d> delta;
705for (int i = 0; i < d; ++i) {
706 delta[i] = P1[i] - P2[i];
707}
708
709return norm2(delta);
710
711};
712
713// -------------------------------------------------------------------------- //
731template<int d, class T, class T1 >
732template< class T2>
734 const T *P_,
735 T2 h,
736 std::vector<T1> *L_,
737 std::vector<T1> *EX_,
738 int next_,
739 int lev
740) {
741
742// ========================================================================== //
743// VARIABLES DECLARATION //
744// ========================================================================== //
745
746// Local variables
747int prev_ = next_;
748int dim;
749
750// Counters
751// none
752
753// ========================================================================== //
754// EXIT FOR EMPTY TREE //
755// ========================================================================== //
756if (n_nodes == 0) { return; };
757
758// ========================================================================== //
759// MOVE ON TREE BRANCHES //
760// ========================================================================== //
761
762// Check if root is in the h-neighbor of P_ --------------------------------- //
763if (distance<T2>(*(nodes[prev_].object_), *P_) <= h) {
764
765 if (EX_ != NULL){
766 if (std::find(EX_->begin(), EX_->end(), nodes[prev_].label) == EX_->end() ) {
767 L_->push_back(nodes[prev_].label);
768 }
769 }
770 else{
771 L_->push_back(nodes[prev_].label);
772 }
773}
774
775
776
777// Move on next branch ------------------------------------------------------ //
778dim = lev % d;
779if (((*(nodes[prev_].object_))[dim] >= (*P_)[dim] - h)
780 && (nodes[prev_].lchild_ >= 0)) {
781 next_ = nodes[prev_].lchild_;
782 hNeighbors(P_, h, L_, EX_, next_, lev+1);
783}
784if (((*(nodes[prev_].object_))[dim] <= (*P_)[dim] + h)
785 && (nodes[prev_].rchild_ >= 0)) {
786 next_ = nodes[prev_].rchild_;
787 hNeighbors(P_, h, L_, EX_, next_, lev+1);
788}
789
790return ;
791
792};
793
794}
void reset(void)
Definition KdTree.tpp:98
class for kd-tree data structure.
KdTree(int stack_size=10)
Definition KdTree.tpp:162
int exist(const T *)
Definition KdTree.tpp:235
void insert(T *)
Definition KdTree.tpp:488
void clear(void)
Definition KdTree.tpp:196
int hNeighbor(const T *, T2, bool, int n=0, int l=0)
Definition KdTree.tpp:361
void hNeighbors(const T *, T2, std::vector< T1 > *, std::vector< T1 > *, int n=0, int l=0)
Definition KdTree.tpp:733
double norm2(const std::array< T, d > &x)
std::array< T, d > max(const std::array< T, d > &x, const std::array< T, d > &y)
--- layout: doxygen_footer ---