GRASS 8 Programmer's Manual 8.6.0dev(2026)-c83afef6d3
Loading...
Searching...
No Matches
kdtree.c
Go to the documentation of this file.
1/*!
2 * \file kdtree.c
3 *
4 * \brief binary search tree
5 *
6 * Dynamic balanced k-d tree implementation
7 *
8 * SPDX-FileCopyrightText: 2014 GRASS Development Team
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 *
11 * \author Markus Metz
12 */
13
14#include <stdlib.h>
15#include <string.h>
16#include <math.h>
17#include <grass/gis.h>
18#include <grass/glocale.h>
19#include "kdtree.h"
20
21#define KD_BTOL 7
22
23#ifdef KD_DEBUG
24#undef KD_DEBUG
25#endif
26
27static int rcalls = 0;
28static int rcallsmax = 0;
29
30static struct kdnode *kdtree_insert2(struct kdtree *, struct kdnode *,
31 struct kdnode *, int, int);
32static int kdtree_replace(struct kdtree *, struct kdnode *);
33static int kdtree_balance(struct kdtree *, struct kdnode *, int);
34static int kdtree_first(struct kdtrav *, double *, int *);
35static int kdtree_next(struct kdtrav *, double *, int *);
36
37static int cmp(struct kdnode *a, struct kdnode *b, int p)
38{
39 if (a->c[p] < b->c[p])
40 return -1;
41 if (a->c[p] > b->c[p])
42 return 1;
43
44 return (a->uid < b->uid ? -1 : a->uid > b->uid);
45}
46
47static int cmpc(struct kdnode *a, struct kdnode *b, struct kdtree *t)
48{
49 int i;
50
51 for (i = 0; i < t->ndims; i++) {
52 if (a->c[i] != b->c[i]) {
53 return 1;
54 }
55 }
56
57 return 0;
58}
59
60static struct kdnode *kdtree_newnode(struct kdtree *t)
61{
62 struct kdnode *n = G_malloc(sizeof(struct kdnode));
63
64 n->c = G_malloc(t->ndims * sizeof(double));
65 n->dim = 0;
66 n->depth = 0;
67 n->balance = 0;
68 n->uid = 0;
69 n->child[0] = NULL;
70 n->child[1] = NULL;
71
72 return n;
73}
74
75static void kdtree_free_node(struct kdnode *n)
76{
77 G_free(n->c);
78 G_free(n);
79}
80
81static void kdtree_update_node(struct kdtree *t, struct kdnode *n)
82{
83 int ld, rd, btol;
84
85 ld = (!n->child[0] ? -1 : n->child[0]->depth);
86 rd = (!n->child[1] ? -1 : n->child[1]->depth);
87 n->depth = MAX(ld, rd) + 1;
88
89 n->balance = 0;
90 /* set balance flag if any of the node's subtrees needs balancing
91 * or if the node itself needs balancing */
92 if ((n->child[0] && n->child[0]->balance) ||
93 (n->child[1] && n->child[1]->balance)) {
94 n->balance = 1;
95
96 return;
97 }
98
99 btol = t->btol;
100 if (!n->child[0] || !n->child[1])
101 btol = 2;
102
103 if (ld > rd + btol || rd > ld + btol)
104 n->balance = 1;
105}
106
107/* create a new k-d tree with ndims dimensions,
108 * optionally set balancing tolerance */
109struct kdtree *kdtree_create(char ndims, int *btol)
110{
111 int i;
112 struct kdtree *t;
113
114 t = G_malloc(sizeof(struct kdtree));
115
116 t->ndims = ndims;
117 t->csize = ndims * sizeof(double);
118 t->btol = KD_BTOL;
119 if (btol) {
120 t->btol = *btol;
121 if (t->btol < 2)
122 t->btol = 2;
123 }
124
125 t->nextdim = G_malloc(ndims * sizeof(char));
126 for (i = 0; i < ndims - 1; i++)
127 t->nextdim[i] = i + 1;
128 t->nextdim[ndims - 1] = 0;
129
130 t->count = 0;
131 t->root = NULL;
132
133 return t;
134}
135
136/* clear the tree, removing all entries */
137void kdtree_clear(struct kdtree *t)
138{
139 struct kdnode *it;
140 struct kdnode *save = t->root;
141
142 /*
143 Rotate away the left links so that
144 we can treat this like the destruction
145 of a linked list
146 */
147 while ((it = save) != NULL) {
148 if (it->child[0] == NULL) {
149 /* No left links, just kill the node and move on */
150 save = it->child[1];
151 kdtree_free_node(it);
152 it = NULL;
153 }
154 else {
155 /* Rotate away the left link and check again */
156 save = it->child[0];
157 it->child[0] = save->child[1];
158 save->child[1] = it;
159 }
160 }
161 t->root = NULL;
162}
163
164/* destroy the tree */
166{
167 /* remove all entries */
169 G_free(t->nextdim);
170
171 G_free(t);
172 t = NULL;
173}
174
175/* insert an item (coordinates c and uid) into the k-d tree
176 * dc == 1: allow duplicate coordinates */
177int kdtree_insert(struct kdtree *t, double *c, int uid, int dc)
178{
179 struct kdnode *nnew;
180 size_t count = t->count;
181
182 nnew = kdtree_newnode(t);
183 memcpy(nnew->c, c, t->csize);
184 nnew->uid = uid;
185
186 t->root = kdtree_insert2(t, t->root, nnew, 1, dc);
187
188 /* print depth of recursion
189 * recursively called fns are insert2, balance, and replace */
190 /*
191 if (rcallsmax > 1)
192 fprintf(stdout, "%d\n", rcallsmax);
193 */
194
195 return count < t->count;
196}
197
198/* remove an item from the k-d tree
199 * coordinates c and uid must match */
200int kdtree_remove(struct kdtree *t, double *c, int uid)
201{
202 struct kdnode sn, *n;
203 struct kdstack {
204 struct kdnode *n;
205 int dir;
206 } s[256];
207 int top;
208 int dir, found;
209 int balance, bmode;
210
211 sn.c = c;
212 sn.uid = uid;
213
214 /* find sn node */
215 top = 0;
216 s[top].n = t->root;
217 dir = 1;
218 found = 0;
219 while (!found) {
220 n = s[top].n;
221 found = (!cmpc(&sn, n, t) && sn.uid == n->uid);
222 if (!found) {
223 dir = cmp(&sn, n, n->dim) > 0;
224 s[top].dir = dir;
225 top++;
226 s[top].n = n->child[dir];
227
228 if (!s[top].n) {
229 G_warning("Node does not exist");
230
231 return 0;
232 }
233 }
234 }
235
236 if (s[top].n->depth == 0) {
237 kdtree_free_node(s[top].n);
238 s[top].n = NULL;
239 if (top) {
240 top--;
241 n = s[top].n;
242 dir = s[top].dir;
243 n->child[dir] = NULL;
244
245 /* update node */
246 kdtree_update_node(t, n);
247 }
248 else {
249 t->root = NULL;
250
251 return 1;
252 }
253 }
254 else
255 kdtree_replace(t, s[top].n);
256
257 while (top) {
258 top--;
259 n = s[top].n;
260
261 /* update node */
262 kdtree_update_node(t, n);
263 }
264
265 balance = 1;
266 bmode = 1;
267 if (balance) {
268 struct kdnode *r;
269 int iter, bmode2;
270
271 /* fix any inconsistencies in the (sub-)tree */
272 iter = 0;
273 bmode2 = 0;
274 top = 0;
275 r = t->root;
276 s[top].n = r;
277 while (top >= 0) {
278
279 n = s[top].n;
280
281 /* top-down balancing
282 * slower but more compact */
283 if (!bmode2) {
284 while (kdtree_balance(t, n, bmode))
285 ;
286 }
287
288 /* go down */
289 if (n->child[0] && n->child[0]->balance) {
290 dir = 0;
291 top++;
292 s[top].n = n->child[dir];
293 }
294 else if (n->child[1] && n->child[1]->balance) {
295 dir = 1;
296 top++;
297 s[top].n = n->child[dir];
298 }
299 /* go back up */
300 else {
301
302 /* bottom-up balancing
303 * faster but less compact */
304 kdtree_update_node(t, n);
305 if (bmode2) {
306 while (kdtree_balance(t, n, bmode))
307 ;
308 }
309 top--;
310 if (top >= 0) {
311 kdtree_update_node(t, s[top].n);
312 }
313 if (!bmode2 && top == 0) {
314 iter++;
315 if (iter == 2) {
316 /* the top node has been visited twice,
317 * switch from top-down to bottom-up balancing */
318 iter = 0;
319 bmode2 = 1;
320 }
321 }
322 }
323 }
324 }
325
326 return 1;
327}
328
329/* k-d tree optimization, only useful if the tree will be used heavily
330 * (more searches than items in the tree)
331 * level 0 = a bit, 1 = more, 2 = a lot */
332void kdtree_optimize(struct kdtree *t, int level)
333{
334 struct kdnode *n, *n2;
335 struct kdstack {
336 struct kdnode *n;
337 int dir;
338 char v;
339 } s[256];
340 int dir;
341 int top;
342 int ld, rd;
343 int diffl, diffr;
344 int nbal;
345
346 if (!t->root)
347 return;
348
349 G_debug(1, "k-d tree optimization for %zd items, tree depth %d", t->count,
350 t->root->depth);
351
352 nbal = 0;
353 top = 0;
354 s[top].n = t->root;
355 while (s[top].n) {
356 n = s[top].n;
357
358 ld = (!n->child[0] ? -1 : n->child[0]->depth);
359 rd = (!n->child[1] ? -1 : n->child[1]->depth);
360
361 if (ld < rd)
362 while (kdtree_balance(t, n->child[0], level))
363 ;
364 else if (ld > rd)
365 while (kdtree_balance(t, n->child[1], level))
366 ;
367
368 ld = (!n->child[0] ? -1 : n->child[0]->depth);
369 rd = (!n->child[1] ? -1 : n->child[1]->depth);
370 n->depth = MAX(ld, rd) + 1;
371
372 dir = (rd > ld);
373
374 top++;
375 s[top].n = n->child[dir];
376 }
377
378 while (top) {
379 top--;
380 n = s[top].n;
381
382 /* balance node */
383 while (kdtree_balance(t, n, level)) {
384 nbal++;
385 }
386 while (kdtree_balance(t, n->child[0], level))
387 ;
388 while (kdtree_balance(t, n->child[1], level))
389 ;
390
391 ld = (!n->child[0] ? -1 : n->child[0]->depth);
392 rd = (!n->child[1] ? -1 : n->child[1]->depth);
393 n->depth = MAX(ld, rd) + 1;
394
395 while (kdtree_balance(t, n, level)) {
396 nbal++;
397 }
398 }
399
400 while (s[top].n) {
401 n = s[top].n;
402
403 /* balance node */
404 while (kdtree_balance(t, n, level)) {
405 nbal++;
406 }
407 while (kdtree_balance(t, n->child[0], level))
408 ;
409 while (kdtree_balance(t, n->child[1], level))
410 ;
411
412 ld = (!n->child[0] ? -1 : n->child[0]->depth);
413 rd = (!n->child[1] ? -1 : n->child[1]->depth);
414 n->depth = MAX(ld, rd) + 1;
415
416 while (kdtree_balance(t, n, level)) {
417 nbal++;
418 }
419
420 ld = (!n->child[0] ? -1 : n->child[0]->depth);
421 rd = (!n->child[1] ? -1 : n->child[1]->depth);
422
423 dir = (rd > ld);
424
425 top++;
426 s[top].n = n->child[dir];
427 }
428
429 while (top) {
430 top--;
431 n = s[top].n;
432
433 /* update node depth */
434 ld = (!n->child[0] ? -1 : n->child[0]->depth);
435 rd = (!n->child[1] ? -1 : n->child[1]->depth);
436 n->depth = MAX(ld, rd) + 1;
437 }
438
439 if (level) {
440 top = 0;
441 s[top].n = t->root;
442 while (s[top].n) {
443 n = s[top].n;
444
445 /* balance node */
446 while (kdtree_balance(t, n, level)) {
447 nbal++;
448 }
449 while (kdtree_balance(t, n->child[0], level))
450 ;
451 while (kdtree_balance(t, n->child[1], level))
452 ;
453
454 ld = (!n->child[0] ? -1 : n->child[0]->depth);
455 rd = (!n->child[1] ? -1 : n->child[1]->depth);
456 n->depth = MAX(ld, rd) + 1;
457
458 while (kdtree_balance(t, n, level)) {
459 nbal++;
460 }
461
462 diffl = diffr = -1;
463 if (n->child[0]) {
464 n2 = n->child[0];
465 ld = (!n2->child[0] ? -1 : n2->child[0]->depth);
466 rd = (!n2->child[1] ? -1 : n2->child[1]->depth);
467
468 diffl = ld - rd;
469 if (diffl < 0)
470 diffl = -diffl;
471 }
472 if (n->child[1]) {
473 n2 = n->child[1];
474 ld = (!n2->child[0] ? -1 : n2->child[0]->depth);
475 rd = (!n2->child[1] ? -1 : n2->child[1]->depth);
476
477 diffr = ld - rd;
478 if (diffr < 0)
479 diffr = -diffr;
480 }
481
482 dir = (diffr > diffl);
483
484 top++;
485 s[top].n = n->child[dir];
486 }
487
488 while (top) {
489 top--;
490 n = s[top].n;
491
492 /* update node depth */
493 ld = (!n->child[0] ? -1 : n->child[0]->depth);
494 rd = (!n->child[1] ? -1 : n->child[1]->depth);
495 n->depth = MAX(ld, rd) + 1;
496 }
497 }
498
499 G_debug(1, "k-d tree optimization: %d times balanced, new depth %d", nbal,
500 t->root->depth);
501
502 return;
503}
504
505/* find k nearest neighbors
506 * results are stored in uid (uids) and d (squared distances)
507 * optionally an uid to be skipped can be given
508 * useful when searching for the nearest neighbors of an item
509 * that is also in the tree */
510int kdtree_knn(struct kdtree *t, double *c, int *uid, double *d, int k,
511 int *skip)
512{
513 int i, found;
514 double diff, dist, maxdist;
515 struct kdnode sn, *n;
516 struct kdstack {
517 struct kdnode *n;
518 int dir;
519 char v;
520 } s[256];
521 int dir;
522 int top;
523
524 if (!t->root)
525 return 0;
526
527 sn.c = c;
528 sn.uid = (int)0x80000000;
529 if (skip)
530 sn.uid = *skip;
531
533 found = 0;
534
535 /* go down */
536 top = 0;
537 s[top].n = t->root;
538 while (s[top].n) {
539 n = s[top].n;
540 dir = cmp(&sn, n, n->dim) > 0;
541 s[top].dir = dir;
542 s[top].v = 0;
543 top++;
544 s[top].n = n->child[dir];
545 }
546
547 /* go back up */
548 while (top) {
549 top--;
550
551 if (!s[top].v) {
552 s[top].v = 1;
553 n = s[top].n;
554
555 if (n->uid != sn.uid) {
556 if (found < k) {
557 dist = 0.0;
558 i = t->ndims - 1;
559 do {
560 diff = sn.c[i] - n->c[i];
561 dist += diff * diff;
562
563 } while (i--);
564
565 i = found;
566 while (i > 0 && d[i - 1] > dist) {
567 d[i] = d[i - 1];
568 uid[i] = uid[i - 1];
569 i--;
570 }
571 if (i < found && d[i] == dist && uid[i] == n->uid)
572 G_fatal_error("knn: inserting duplicate");
573 d[i] = dist;
574 uid[i] = n->uid;
575 maxdist = d[found];
576 found++;
577 }
578 else {
579 dist = 0.0;
580 i = t->ndims - 1;
581 do {
582 diff = sn.c[i] - n->c[i];
583 dist += diff * diff;
584
585 } while (i-- && dist <= maxdist);
586
587 if (dist < maxdist) {
588 i = k - 1;
589 while (i > 0 && d[i - 1] > dist) {
590 d[i] = d[i - 1];
591 uid[i] = uid[i - 1];
592 i--;
593 }
594 if (d[i] == dist && uid[i] == n->uid)
595 G_fatal_error("knn: inserting duplicate");
596 d[i] = dist;
597 uid[i] = n->uid;
598
599 maxdist = d[k - 1];
600 }
601 }
602 if (found == k && maxdist == 0.0)
603 break;
604 }
605
606 /* look on the other side ? */
607 dir = s[top].dir;
608 diff = sn.c[(int)n->dim] - n->c[(int)n->dim];
609 dist = diff * diff;
610
611 if (dist <= maxdist) {
612 /* go down the other side */
613 top++;
614 s[top].n = n->child[!dir];
615 while (s[top].n) {
616 n = s[top].n;
617 dir = cmp(&sn, n, n->dim) > 0;
618 s[top].dir = dir;
619 s[top].v = 0;
620 top++;
621 s[top].n = n->child[dir];
622 }
623 }
624 }
625 }
626
627 return found;
628}
629
630/* find all nearest neighbors within distance aka radius search
631 * results are stored in puid (uids) and pd (squared distances)
632 * memory is allocated as needed, the calling fn must free the memory
633 * optionally an uid to be skipped can be given */
634int kdtree_dnn(struct kdtree *t, double *c, int **puid, double **pd,
635 double maxdist, int *skip)
636{
637 int i, k, found;
638 double diff, dist;
639 struct kdnode sn, *n;
640 struct kdstack {
641 struct kdnode *n;
642 int dir;
643 char v;
644 } s[256];
645 int dir;
646 int top;
647 int *uid;
648 double *d, maxdistsq;
649
650 if (!t->root)
651 return 0;
652
653 sn.c = c;
654 sn.uid = (int)0x80000000;
655 if (skip)
656 sn.uid = *skip;
657
658 *pd = NULL;
659 *puid = NULL;
660
661 k = 0;
662 uid = NULL;
663 d = NULL;
664
665 found = 0;
667
668 /* go down */
669 top = 0;
670 s[top].n = t->root;
671 while (s[top].n) {
672 n = s[top].n;
673 dir = cmp(&sn, n, n->dim) > 0;
674 s[top].dir = dir;
675 s[top].v = 0;
676 top++;
677 s[top].n = n->child[dir];
678 }
679
680 /* go back up */
681 while (top) {
682 top--;
683
684 if (!s[top].v) {
685 s[top].v = 1;
686 n = s[top].n;
687
688 if (n->uid != sn.uid) {
689 dist = 0;
690 i = t->ndims - 1;
691 do {
692 diff = sn.c[i] - n->c[i];
693 dist += diff * diff;
694
695 } while (i-- && dist <= maxdistsq);
696
697 if (dist <= maxdistsq) {
698 if (found + 1 >= k) {
699 k = found + 10;
700 uid = G_realloc(uid, k * sizeof(int));
701 d = G_realloc(d, k * sizeof(double));
702 }
703 i = found;
704 while (i > 0 && d[i - 1] > dist) {
705 d[i] = d[i - 1];
706 uid[i] = uid[i - 1];
707 i--;
708 }
709 if (i < found && d[i] == dist && uid[i] == n->uid)
710 G_fatal_error("dnn: inserting duplicate");
711 d[i] = dist;
712 uid[i] = n->uid;
713 found++;
714 }
715 }
716
717 /* look on the other side ? */
718 dir = s[top].dir;
719
720 diff = fabs(sn.c[(int)n->dim] - n->c[(int)n->dim]);
721 if (diff <= maxdist) {
722 /* go down the other side */
723 top++;
724 s[top].n = n->child[!dir];
725 while (s[top].n) {
726 n = s[top].n;
727 dir = cmp(&sn, n, n->dim) > 0;
728 s[top].dir = dir;
729 s[top].v = 0;
730 top++;
731 s[top].n = n->child[dir];
732 }
733 }
734 }
735 }
736
737 *pd = d;
738 *puid = uid;
739
740 return found;
741}
742
743/* find all nearest neighbors within range aka box search
744 * the range is specified with min and max for each dimension as
745 * (min1, min2, ..., minn, max1, max2, ..., maxn)
746 * results are stored in puid (uids)
747 * memory is allocated as needed, the calling fn must free the memory
748 * optionally an uid to be skipped can be given */
749int kdtree_rnn(struct kdtree *t, double *c, int **puid, int *skip)
750{
751 int i, k, found, inside;
752 struct kdnode sn, *n;
753 struct kdstack {
754 struct kdnode *n;
755 int dir;
756 char v;
757 } s[256];
758 int dir;
759 int top;
760 int *uid;
761
762 if (!t->root)
763 return 0;
764
765 sn.c = c;
766 sn.uid = (int)0x80000000;
767 if (skip)
768 sn.uid = *skip;
769
770 *puid = NULL;
771
772 k = 0;
773 uid = NULL;
774
775 found = 0;
776
777 /* go down */
778 top = 0;
779 s[top].n = t->root;
780 while (s[top].n) {
781 n = s[top].n;
782 dir = cmp(&sn, n, n->dim) > 0;
783 s[top].dir = dir;
784 s[top].v = 0;
785 top++;
786 s[top].n = n->child[dir];
787 }
788
789 /* go back up */
790 while (top) {
791 top--;
792
793 if (!s[top].v) {
794 s[top].v = 1;
795 n = s[top].n;
796
797 if (n->uid != sn.uid) {
798 inside = 1;
799 for (i = 0; i < t->ndims; i++) {
800 if (n->c[i] < sn.c[i] || n->c[i] > sn.c[i + t->ndims]) {
801 inside = 0;
802 break;
803 }
804 }
805
806 if (inside) {
807 if (found + 1 >= k) {
808 k = found + 10;
809 uid = G_realloc(uid, k * sizeof(int));
810 }
811 i = found;
812 uid[i] = n->uid;
813 found++;
814 }
815 }
816
817 /* look on the other side ? */
818 dir = s[top].dir;
819 if (n->c[(int)n->dim] >= sn.c[(int)n->dim] &&
820 n->c[(int)n->dim] <= sn.c[(int)n->dim + t->ndims]) {
821 /* go down the other side */
822 top++;
823 s[top].n = n->child[!dir];
824 while (s[top].n) {
825 n = s[top].n;
826 dir = cmp(&sn, n, n->dim) > 0;
827 s[top].dir = dir;
828 s[top].v = 0;
829 top++;
830 s[top].n = n->child[dir];
831 }
832 }
833 }
834 }
835
836 *puid = uid;
837
838 return found;
839}
840
841/* initialize tree traversal
842 * (re-)sets trav structure
843 * returns 0
844 */
845int kdtree_init_trav(struct kdtrav *trav, struct kdtree *tree)
846{
847 trav->tree = tree;
848 trav->curr_node = tree->root;
849 trav->first = 1;
850 trav->top = 0;
851
852 return 0;
853}
854
855/* traverse the tree
856 * useful to get all items in the tree non-recursively
857 * struct kdtrav *trav needs to be initialized first
858 * returns 1, 0 when finished
859 */
860int kdtree_traverse(struct kdtrav *trav, double *c, int *uid)
861{
862 if (trav->curr_node == NULL) {
863 if (trav->first)
864 G_debug(1, "k-d tree: empty tree");
865 else
866 G_debug(1, "k-d tree: finished traversing");
867
868 return 0;
869 }
870
871 if (trav->first) {
872 trav->first = 0;
873 return kdtree_first(trav, c, uid);
874 }
875
876 return kdtree_next(trav, c, uid);
877}
878
879/**********************************************/
880/* internal functions */
881
882/**********************************************/
883
884static int kdtree_replace(struct kdtree *t, struct kdnode *r)
885{
886 double mindist;
887 int rdir, ordir, dir;
888 int ld, rd;
889 struct kdnode *n, *rn, *or;
890 struct kdstack {
891 struct kdnode *n;
892 int dir;
893 char v;
894 } s[256];
895 int top, top2;
896 int is_leaf;
897 int nr;
898
899 if (!r)
900 return 0;
901 if (!r->child[0] && !r->child[1])
902 return 0;
903
904 /* do not call kdtree_balance in this fn, this can cause
905 * stack overflow due to too many recursive calls */
906
907 /* find replacement for r
908 * overwrite r, delete replacement */
909 nr = 0;
910
911 /* pick a subtree */
912 rdir = 1;
913
914 or = r;
915 ld = (!or->child[0] ? -1 : or->child[0]->depth);
916 rd = (!or->child[1] ? -1 : or->child[1]->depth);
917
918 if (ld > rd) {
919 rdir = 0;
920 }
921
922 /* replace old root, make replacement the new root
923 * repeat until replacement is leaf */
924 ordir = rdir;
925 is_leaf = 0;
926 s[0].n = or;
927 s[0].dir = ordir;
928 top2 = 1;
929 mindist = -1;
930 while (!is_leaf) {
931 rn = NULL;
932
933 /* find replacement for old root */
934 top = top2;
935 s[top].n = or->child[ordir];
936
937 n = s[top].n;
938 rn = n;
939 mindist = or->c[(int)or->dim] - n->c[(int)or->dim];
940 if (ordir)
941 mindist = -mindist;
942
943 /* go down */
944 while (s[top].n) {
945 n = s[top].n;
946 dir = !ordir;
947 if (n->dim != or->dim)
948 dir = cmp(or, n, n->dim) > 0;
949 s[top].dir = dir;
950 s[top].v = 0;
951 top++;
952 s[top].n = n->child[dir];
953 }
954
955 /* go back up */
956 while (top > top2) {
957 top--;
958
959 if (!s[top].v) {
960 s[top].v = 1;
961 n = s[top].n;
962 if ((cmp(rn, n, or->dim) > 0) == ordir) {
963 rn = n;
964 mindist = or->c[(int)or->dim] - n->c[(int)or->dim];
965 if (ordir)
966 mindist = -mindist;
967 }
968
969 /* look on the other side ? */
970 dir = s[top].dir;
971 if (n->dim != or->dim &&
972 mindist >= fabs(n->c[(int)n->dim] - n->c[(int)n->dim])) {
973 /* go down the other side */
974 top++;
975 s[top].n = n->child[!dir];
976 while (s[top].n) {
977 n = s[top].n;
978 dir = !ordir;
979 if (n->dim != or->dim)
980 dir = cmp(or, n, n->dim) > 0;
981 s[top].dir = dir;
982 s[top].v = 0;
983 top++;
984 s[top].n = n->child[dir];
985 }
986 }
987 }
988 }
989
990#ifdef KD_DEBUG
991 if (!rn)
992 G_fatal_error("No replacement");
993 if (ordir && or->c[(int)or->dim] > rn->c[(int)or->dim])
994 G_fatal_error("rn is smaller");
995
996 if (!ordir && or->c[(int)or->dim] < rn->c[(int)or->dim])
997 G_fatal_error("rn is larger");
998
999 if (or->child[1]) {
1000 dir = cmp(or->child[1], rn, or->dim);
1001 if (dir < 0) {
1002 int i;
1003
1004 for (i = 0; i < t->ndims; i++)
1005 G_message("rn c %g, or child c %g", rn->c[i],
1006 or->child[1]->c[i]);
1008 "Right child of old root is smaller than rn, dir is %d",
1009 ordir);
1010 }
1011 }
1012 if (or->child[0]) {
1013 dir = cmp(or->child[0], rn, or->dim);
1014 if (dir > 0) {
1015 int i;
1016
1017 for (i = 0; i < t->ndims; i++)
1018 G_message("rn c %g, or child c %g", rn->c[i],
1019 or->child[0]->c[i]);
1021 "Left child of old root is larger than rn, dir is %d",
1022 ordir);
1023 }
1024 }
1025#endif
1026
1027 is_leaf = (rn->child[0] == NULL && rn->child[1] == NULL);
1028
1029#ifdef KD_DEBUG
1030 if (is_leaf && rn->depth != 0)
1031 G_fatal_error("rn is leaf but depth is %d", (int)rn->depth);
1032 if (!is_leaf && rn->depth <= 0)
1033 G_fatal_error("rn is not leaf but depth is %d", (int)rn->depth);
1034#endif
1035
1036 nr++;
1037
1038 /* go to replacement from or->child[ordir] */
1039 top = top2;
1040 dir = 1;
1041 while (dir) {
1042 n = s[top].n;
1043 dir = cmp(rn, n, n->dim);
1044 if (dir) {
1045 s[top].dir = dir > 0;
1046 top++;
1047 s[top].n = n->child[dir > 0];
1048
1049 if (!s[top].n) {
1050 G_fatal_error("(Last) replacement disappeared %d", nr);
1051 }
1052 }
1053 }
1054
1055#ifdef KD_DEBUG
1056 if (s[top].n != rn)
1057 G_fatal_error("rn is unreachable from or");
1058#endif
1059
1060 top2 = top;
1061 s[top2 + 1].n = NULL;
1062
1063 /* copy replacement to old root */
1064 memcpy(or->c, rn->c, t->csize);
1065 or->uid = rn->uid;
1066
1067 if (!is_leaf) {
1068 /* make replacement the old root */
1069 or = rn;
1070
1071 /* pick a subtree */
1072 ordir = 1;
1073 ld = (!or->child[0] ? -1 : or->child[0]->depth);
1074 rd = (!or->child[1] ? -1 : or->child[1]->depth);
1075 if (ld > rd) {
1076 ordir = 0;
1077 }
1078 s[top2].dir = ordir;
1079 top2++;
1080 }
1081 }
1082
1083 if (!rn)
1084 G_fatal_error("No replacement at all");
1085
1086 /* delete last replacement */
1087 if (s[top2].n != rn) {
1088 G_fatal_error("Wrong top2 for last replacement");
1089 }
1090 top = top2 - 1;
1091 n = s[top].n;
1092 dir = s[top].dir;
1093 if (n->child[dir] != rn) {
1094 G_fatal_error("Last replacement disappeared");
1095 }
1096 kdtree_free_node(rn);
1097 n->child[dir] = NULL;
1098 t->count--;
1099
1100 kdtree_update_node(t, n);
1101 top++;
1102
1103 /* go back up */
1104 while (top) {
1105 top--;
1106 n = s[top].n;
1107
1108#ifdef KD_DEBUG
1109 /* debug directions */
1110 if (n->child[0]) {
1111 if (cmp(n->child[0], n, n->dim) > 0)
1112 G_warning("Left child is larger");
1113 }
1114 if (n->child[1]) {
1115 if (cmp(n->child[1], n, n->dim) < 1)
1116 G_warning("Right child is not larger");
1117 }
1118#endif
1119
1120 /* update node */
1121 kdtree_update_node(t, n);
1122 }
1123
1124 return nr;
1125}
1126
1127static int kdtree_balance(struct kdtree *t, struct kdnode *r, int bmode)
1128{
1129 struct kdnode *or;
1130 int dir;
1131 int rd, ld;
1132 int old_depth;
1133 int btol;
1134
1135 if (!r) {
1136 return 0;
1137 }
1138
1139 ld = (!r->child[0] ? -1 : r->child[0]->depth);
1140 rd = (!r->child[1] ? -1 : r->child[1]->depth);
1141 old_depth = MAX(ld, rd) + 1;
1142
1143 if (old_depth != r->depth) {
1144 G_warning("balancing: depth is wrong: %d != %d", r->depth, old_depth);
1145 kdtree_update_node(t, r);
1146 }
1147
1148 /* subtree difference */
1149 btol = t->btol;
1150 if (!r->child[0] || !r->child[1])
1151 btol = 2;
1152 dir = -1;
1153 ld = (!r->child[0] ? -1 : r->child[0]->depth);
1154 rd = (!r->child[1] ? -1 : r->child[1]->depth);
1155 if (ld > rd + btol) {
1156 dir = 0;
1157 }
1158 else if (rd > ld + btol) {
1159 dir = 1;
1160 }
1161 else {
1162 return 0;
1163 }
1164
1165 or = kdtree_newnode(t);
1166 memcpy(or->c, r->c, t->csize);
1167 or->uid = r->uid;
1168 or->dim = t->nextdim[r->dim];
1169
1170 if (!kdtree_replace(t, r))
1171 G_fatal_error("kdtree_balance: nothing replaced");
1172
1173#ifdef KD_DEBUG
1174 if (!cmp(r, or, r->dim)) {
1175 G_warning("kdtree_balance: replacement failed");
1176 kdtree_free_node(or);
1177
1178 return 0;
1179 }
1180#endif
1181
1182 r->child[!dir] =
1183 kdtree_insert2(t, r->child[!dir], or, bmode, 1); /* bmode */
1184
1185 /* update node */
1186 kdtree_update_node(t, r);
1187
1188 if (r->depth == old_depth) {
1189 G_debug(4, "balancing had no effect");
1190 return 1;
1191 }
1192
1193 if (r->depth > old_depth)
1194 G_fatal_error("balancing failed");
1195
1196 return 1;
1197}
1198
1199static struct kdnode *kdtree_insert2(struct kdtree *t, struct kdnode *r,
1200 struct kdnode *nnew, int balance, int dc)
1201{
1202 struct kdnode *n;
1203 struct kdstack {
1204 struct kdnode *n;
1205 int dir;
1206 } s[256];
1207 int top;
1208 int dir;
1209 int bmode;
1210
1211 if (!r) {
1212 r = nnew;
1213 t->count++;
1214
1215 return r;
1216 }
1217
1218 /* level of recursion */
1219 rcalls++;
1220 if (rcallsmax < rcalls)
1221 rcallsmax = rcalls;
1222
1223 /* balancing modes
1224 * bmode = 0: no recursion (only insert -> balance -> insert)
1225 * slower, higher tree depth
1226 * bmode = 1: recursion (insert -> balance -> insert -> balance ...)
1227 * faster, more compact tree
1228 * */
1229 bmode = 1;
1230
1231 /* find node with free child */
1232 top = 0;
1233 s[top].n = r;
1234 while (s[top].n) {
1235
1236 n = s[top].n;
1237
1238 if (!cmpc(nnew, n, t) && (!dc || nnew->uid == n->uid)) {
1239
1240 G_debug(1, "KD node exists already, nothing to do");
1241 kdtree_free_node(nnew);
1242
1243 if (!balance) {
1244 rcalls--;
1245 return r;
1246 }
1247
1248 break;
1249 }
1250 dir = cmp(nnew, n, n->dim) > 0;
1251 s[top].dir = dir;
1252
1253 top++;
1254 if (top > 255)
1255 G_fatal_error("depth too large: %d", top);
1256 s[top].n = n->child[dir];
1257 }
1258
1259 if (!s[top].n) {
1260 /* insert to child pointer of parent */
1261 top--;
1262 n = s[top].n;
1263 dir = s[top].dir;
1264 n->child[dir] = nnew;
1265 nnew->dim = t->nextdim[n->dim];
1266
1267 t->count++;
1268 top++;
1269 }
1270
1271 /* go back up */
1272 while (top) {
1273 top--;
1274 n = s[top].n;
1275
1276 /* update node */
1277 kdtree_update_node(t, n);
1278
1279 /* do not balance on the way back up */
1280
1281#ifdef KD_DEBUG
1282 /* debug directions */
1283 if (n->child[0]) {
1284 if (cmp(n->child[0], n, n->dim) > 0)
1285 G_warning("Insert2: Left child is larger");
1286 }
1287 if (n->child[1]) {
1288 if (cmp(n->child[1], n, n->dim) < 1)
1289 G_warning("Insert2: Right child is not larger");
1290 }
1291#endif
1292 }
1293
1294 if (balance) {
1295 int iter, bmode2;
1296
1297 /* fix any inconsistencies in the (sub-)tree */
1298 iter = 0;
1299 bmode2 = 0;
1300 top = 0;
1301 s[top].n = r;
1302 while (top >= 0) {
1303
1304 n = s[top].n;
1305
1306 /* top-down balancing
1307 * slower but more compact */
1308 if (!bmode2) {
1309 while (kdtree_balance(t, n, bmode))
1310 ;
1311 }
1312
1313 /* go down */
1314 if (n->child[0] && n->child[0]->balance) {
1315 dir = 0;
1316 top++;
1317 s[top].n = n->child[dir];
1318 }
1319 else if (n->child[1] && n->child[1]->balance) {
1320 dir = 1;
1321 top++;
1322 s[top].n = n->child[dir];
1323 }
1324 /* go back up */
1325 else {
1326
1327 /* bottom-up balancing
1328 * faster but less compact */
1329 if (bmode2) {
1330 while (kdtree_balance(t, n, bmode))
1331 ;
1332 }
1333 top--;
1334 if (top >= 0) {
1335 kdtree_update_node(t, s[top].n);
1336 }
1337 if (!bmode2 && top == 0) {
1338 iter++;
1339 if (iter == 2) {
1340 /* the top node has been visited twice,
1341 * switch from top-down to bottom-up balancing */
1342 iter = 0;
1343 bmode2 = 1;
1344 }
1345 }
1346 }
1347 }
1348 }
1349
1350 rcalls--;
1351
1352 return r;
1353}
1354
1355/* start traversing the tree
1356 * returns pointer to first item
1357 */
1358static int kdtree_first(struct kdtrav *trav, double *c, int *uid)
1359{
1360 /* get smallest item */
1361 while (trav->curr_node->child[0] != NULL) {
1362 trav->up[trav->top++] = trav->curr_node;
1363 trav->curr_node = trav->curr_node->child[0];
1364 }
1365
1366 memcpy(c, trav->curr_node->c, trav->tree->csize);
1367 *uid = trav->curr_node->uid;
1368
1369 return 1;
1370}
1371
1372/* continue traversing the tree in ascending order
1373 * returns pointer to data item, NULL when finished
1374 */
1375static int kdtree_next(struct kdtrav *trav, double *c, int *uid)
1376{
1377 if (trav->curr_node->child[1] != NULL) {
1378 /* something on the right side: larger item */
1379 trav->up[trav->top++] = trav->curr_node;
1380 trav->curr_node = trav->curr_node->child[1];
1381
1382 /* go down, find smallest item in this branch */
1383 while (trav->curr_node->child[0] != NULL) {
1384 trav->up[trav->top++] = trav->curr_node;
1385 trav->curr_node = trav->curr_node->child[0];
1386 }
1387 }
1388 else {
1389 /* at smallest item in this branch, go back up */
1390 struct kdnode *last;
1391
1392 do {
1393 if (trav->top == 0) {
1394 trav->curr_node = NULL;
1395 break;
1396 }
1397 last = trav->curr_node;
1398 trav->curr_node = trav->up[--trav->top];
1399 } while (last == trav->curr_node->child[1]);
1400 }
1401
1402 if (trav->curr_node != NULL) {
1403 memcpy(c, trav->curr_node->c, trav->tree->csize);
1404 *uid = trav->curr_node->uid;
1405
1406 return 1;
1407 }
1408
1409 return 0; /* finished traversing */
1410}
#define NULL
Definition ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
#define G_realloc(p, n)
Definition defs/gis.h:138
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition defs/gis.h:136
void G_message(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
#define MAX(a, b)
Definition gis.h:145
int count
void kdtree_optimize(struct kdtree *t, int level)
Definition kdtree.c:332
int kdtree_rnn(struct kdtree *t, double *c, int **puid, int *skip)
Definition kdtree.c:749
struct kdtree * kdtree_create(char ndims, int *btol)
Definition kdtree.c:109
int kdtree_traverse(struct kdtrav *trav, double *c, int *uid)
Definition kdtree.c:860
void kdtree_clear(struct kdtree *t)
Definition kdtree.c:137
int kdtree_insert(struct kdtree *t, double *c, int uid, int dc)
Definition kdtree.c:177
int kdtree_knn(struct kdtree *t, double *c, int *uid, double *d, int k, int *skip)
Definition kdtree.c:510
void kdtree_destroy(struct kdtree *t)
Definition kdtree.c:165
int kdtree_dnn(struct kdtree *t, double *c, int **puid, double **pd, double maxdist, int *skip)
Definition kdtree.c:634
#define KD_BTOL
Definition kdtree.c:21
int kdtree_init_trav(struct kdtrav *trav, struct kdtree *tree)
Definition kdtree.c:845
int kdtree_remove(struct kdtree *t, double *c, int uid)
Definition kdtree.c:200
Dynamic balanced k-d tree implementation.
double b
Definition r_raster.c:37
double t
Definition r_raster.c:37
double r
Definition r_raster.c:37
Node for k-d tree.
Definition kdtree.h:65
unsigned char dim
Definition kdtree.h:66
unsigned char balance
Definition kdtree.h:68
unsigned char depth
Definition kdtree.h:67
struct kdnode * child[2]
Definition kdtree.h:71
int uid
Definition kdtree.h:70
double * c
Definition kdtree.h:69
k-d tree traversal
Definition kdtree.h:90
k-d tree
Definition kdtree.h:78
unsigned char ndims
Definition kdtree.h:79
int btol
Definition kdtree.h:82
struct kdnode * root
Definition kdtree.h:84