ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
kd_tree.f90
Go to the documentation of this file.
1 !
2 !(c) Matthew Kennel, Institute for Nonlinear Science (2004)
3 !
4 ! Licensed under the Academic Free License version 1.1 found in file LICENSE
5 ! with additional provisions found in that same file.
6 !
7 
9  use precision
10  implicit none
11  !
12  ! maintain a priority queue (PQ) of data, pairs of 'priority/payload',
13  ! implemented with a binary heap. This is the type, and the 'dis' field
14  ! is the priority.
15  !
17  ! a pair of distances, indexes
18  real(kind=realtype) :: dis!=0.0
19  integer(kind=intType) :: idx!=-1 Initializers cause some bugs in compilers.
20  end type kdtree2_result
21  !
22  ! A heap-based priority queue lets one efficiently implement the following
23  ! operations, each in log(N) time, as opposed to linear time.
24  !
25  ! 1) add a datum (push a datum onto the queue, increasing its length)
26  ! 2) return the priority value of the maximum priority element
27  ! 3) pop-off (and delete) the element with the maximum priority, decreasing
28  ! the size of the queue.
29  ! 4) replace the datum with the maximum priority with a supplied datum
30  ! (of either higher or lower priority), maintaining the size of the
31  ! queue.
32  !
33  !
34  ! In the k-d tree case, the 'priority' is the square distance of a point in
35  ! the data set to a reference point. The goal is to keep the smallest M
36  ! distances to a reference point. The tree algorithm searches terminal
37  ! nodes to decide whether to add points under consideration.
38  !
39  ! A priority queue is useful here because it lets one quickly return the
40  ! largest distance currently existing in the list. If a new candidate
41  ! distance is smaller than this, then the new candidate ought to replace
42  ! the old candidate. In priority queue terms, this means removing the
43  ! highest priority element, and inserting the new one.
44  !
45  ! Algorithms based on Cormen, Leiserson, Rivest, _Introduction
46  ! to Algorithms_, 1990, with further optimization by the author.
47  !
48  ! Originally informed by a C implementation by Sriranga Veeraraghavan.
49  !
50  ! This module is not written in the most clear way, but is implemented such
51  ! for speed, as it its operations will be called many times during searches
52  ! of large numbers of neighbors.
53  !
54  type pq
55  !
56  ! The priority queue consists of elements
57  ! priority(1:heap_size), with associated payload(:).
58  !
59  ! There are heap_size active elements.
60  ! Assumes the allocation is always sufficient. Will NOT increase it
61  ! to match.
62  integer(kind=intType) :: heap_size = 0
63  type(kdtree2_result), pointer :: elems(:)
64  end type pq
65 
66  public :: kdtree2_result
67 
68  public :: pq
69  public :: pq_create
70  public :: pq_delete, pq_insert
72  private
73 
74 contains
75 
76  function pq_create(results_in) result(res)
77  implicit none
78  !
79  ! Create a priority queue from ALREADY allocated
80  ! array pointers for storage. NOTE! It will NOT
81  ! add any alements to the heap, i.e. any existing
82  ! data in the input arrays will NOT be used and may
83  ! be overwritten.
84  !
85  ! usage:
86  ! real(kind=realType), pointer :: x(:)
87  ! integer(kind=intType), pointer :: k(:)
88  ! allocate(x(1000),k(1000))
89  ! pq => pq_create(x,k)
90  !
91  type(kdtree2_result), target :: results_in(:)
92  type(pq) :: res
93  !
94  !
95  integer(kind=intType) :: nalloc
96 
97  nalloc = size(results_in, 1)
98  if (nalloc .lt. 1) then
99  write (*, *) 'PQ_CREATE: error, input arrays must be allocated.'
100  end if
101  res%elems => results_in
102  res%heap_size = 0
103  return
104  end function pq_create
105 
106  !
107  ! operations for getting parents and left + right children
108  ! of elements in a binary heap.
109  !
110 
111  !
112  ! These are written inline for speed.
113  !
114  ! integer(kind=intType) function parent(i)
115  ! integer(kind=intType), intent(in) :: i
116  ! parent = (i/2)
117  ! return
118  ! end function parent
119 
120  ! integer(kind=intType) function left(i)
121  ! integer(kind=intType), intent(in) ::i
122  ! left = (2*i)
123  ! return
124  ! end function left
125 
126  ! integer(kind=intType) function right(i)
127  ! integer(kind=intType), intent(in) :: i
128  ! right = (2*i)+1
129  ! return
130  ! end function right
131 
132  ! logical function compare_priority(p1,p2)
133  ! real(kind=realType), intent(in) :: p1, p2
134  !
135  ! compare_priority = (p1 .gt. p2)
136  ! return
137  ! end function compare_priority
138 
139  subroutine heapify(a, i_in)
140  implicit none
141  !
142  ! take a heap rooted at 'i' and force it to be in the
143  ! heap canonical form. This is performance critical
144  ! and has been tweaked a little to reflect this.
145  !
146  type(pq), pointer :: a
147  integer(kind=intType), intent(in) :: i_in
148  !
149  integer(kind=intType) :: i, l, r, largest
150 
151  real(kind=realtype) :: pri_i, pri_l, pri_r, pri_largest
152 
153  type(kdtree2_result) :: temp
154 
155  i = i_in
156 
157  bigloop: do
158  l = 2 * i ! left(i)
159  r = l + 1 ! right(i)
160  !
161  ! set 'largest' to the index of either i, l, r
162  ! depending on whose priority is largest.
163  !
164  ! note that l or r can be larger than the heap size
165  ! in which case they do not count.
166 
167  ! does left child have higher priority?
168  if (l .gt. a%heap_size) then
169  ! we know that i is the largest as both l and r are invalid.
170  exit
171  else
172  pri_i = a%elems(i)%dis
173  pri_l = a%elems(l)%dis
174  if (pri_l .gt. pri_i) then
175  largest = l
176  pri_largest = pri_l
177  else
178  largest = i
179  pri_largest = pri_i
180  end if
181 
182  !
183  ! between i and l we have a winner
184  ! now choose between that and r.
185  !
186  if (r .le. a%heap_size) then
187  pri_r = a%elems(r)%dis
188  if (pri_r .gt. pri_largest) then
189  largest = r
190  end if
191  end if
192  end if
193 
194  if (largest .ne. i) then
195  ! swap data in nodes largest and i, then heapify
196 
197  temp = a%elems(i)
198  a%elems(i) = a%elems(largest)
199  a%elems(largest) = temp
200  !
201  ! Canonical heapify() algorithm has tail-ecursive call:
202  !
203  ! call heapify(a,largest)
204  ! we will simulate with cycle
205  !
206  i = largest
207  cycle bigloop ! continue the loop
208  else
209  return ! break from the loop
210  end if
211  end do bigloop
212  return
213  end subroutine heapify
214 
215  subroutine pq_max(a, e)
216  implicit none
217  !
218  ! return the priority and its payload of the maximum priority element
219  ! on the queue, which should be the first one, if it is
220  ! in heapified form.
221  !
222  type(pq), pointer :: a
223  type(kdtree2_result), intent(out) :: e
224 
225  if (a%heap_size .gt. 0) then
226  e = a%elems(1)
227  else
228  write (*, *) 'PQ_MAX: ERROR, heap_size < 1'
229  stop
230  end if
231  return
232  end subroutine pq_max
233 
234  real(kind=realtype) function pq_maxpri(a)
235  implicit none
236  type(pq), pointer :: a
237 
238  if (a%heap_size .gt. 0) then
239  pq_maxpri = a%elems(1)%dis
240  else
241  write (*, *) 'PQ_MAX_PRI: ERROR, heapsize < 1'
242  stop
243  end if
244  return
245  end function pq_maxpri
246 
247  subroutine pq_extract_max(a, e)
248  implicit none
249  !
250  ! return the priority and payload of maximum priority
251  ! element, and remove it from the queue.
252  ! (equivalent to 'pop()' on a stack)
253  !
254  type(pq), pointer :: a
255  type(kdtree2_result), intent(out) :: e
256 
257  if (a%heap_size .ge. 1) then
258  !
259  ! return max as first element
260  !
261  e = a%elems(1)
262 
263  !
264  ! move last element to first
265  !
266  a%elems(1) = a%elems(a%heap_size)
267  a%heap_size = a%heap_size - 1
268  call heapify(a, 1)
269  return
270  else
271  write (*, *) 'PQ_EXTRACT_MAX: error, attempted to pop non-positive PQ'
272  stop
273  end if
274 
275  end subroutine pq_extract_max
276 
277  real(kind=realtype) function pq_insert(a, dis, idx)
278  implicit none
279  !
280  ! Insert a new element and return the new maximum priority,
281  ! which may or may not be the same as the old maximum priority.
282  !
283  type(pq), pointer :: a
284  real(kind=realtype), intent(in) :: dis
285  integer(kind=intType), intent(in) :: idx
286  ! type(kdtree2_result), intent(in) :: e
287  !
288  integer(kind=intType) :: i, isparent
289  real(kind=realtype) :: parentdis
290  !
291 
292  ! if (a%heap_size .ge. a%max_elems) then
293  ! write (*,*) 'PQ_INSERT: error, attempt made to insert element on full PQ'
294  ! stop
295  ! else
296  a%heap_size = a%heap_size + 1
297  i = a%heap_size
298 
299  do while (i .gt. 1)
300  isparent = int(i / 2)
301  parentdis = a%elems(isparent)%dis
302  if (dis .gt. parentdis) then
303  ! move what was in i's parent into i.
304  a%elems(i)%dis = parentdis
305  a%elems(i)%idx = a%elems(isparent)%idx
306  i = isparent
307  else
308  exit
309  end if
310  end do
311 
312  ! insert the element at the determined position
313  a%elems(i)%dis = dis
314  a%elems(i)%idx = idx
315 
316  pq_insert = a%elems(1)%dis
317  return
318  ! end if
319 
320  end function pq_insert
321 
322  subroutine pq_adjust_heap(a, i)
323  implicit none
324  type(pq), pointer :: a
325  integer(kind=intType), intent(in) :: i
326  !
327  ! nominally arguments (a,i), but specialize for a=1
328  !
329  ! This routine assumes that the trees with roots 2 and 3 are already heaps, i.e.
330  ! the children of '1' are heaps. When the procedure is completed, the
331  ! tree rooted at 1 is a heap.
332  real(kind=realtype) :: prichild
333  integer(kind=intType) :: parent, child, n
334 
335  type(kdtree2_result) :: e
336 
337  e = a%elems(i)
338 
339  parent = i
340  child = 2 * i
341  n = a%heap_size
342 
343  do while (child .le. n)
344  if (child .lt. n) then
345  if (a%elems(child)%dis .lt. a%elems(child + 1)%dis) then
346  child = child + 1
347  end if
348  end if
349  prichild = a%elems(child)%dis
350  if (e%dis .ge. prichild) then
351  exit
352  else
353  ! move child into parent.
354  a%elems(parent) = a%elems(child)
355  parent = child
356  child = 2 * parent
357  end if
358  end do
359  a%elems(parent) = e
360  return
361  end subroutine pq_adjust_heap
362 
363  real(kind=realtype) function pq_replace_max(a, dis, idx)
364  implicit none
365  !
366  ! Replace the extant maximum priority element
367  ! in the PQ with (dis,idx). Return
368  ! the new maximum priority, which may be larger
369  ! or smaller than the old one.
370  !
371  type(pq), pointer :: a
372  real(kind=realtype), intent(in) :: dis
373  integer(kind=intType), intent(in) :: idx
374  ! type(kdtree2_result), intent(in) :: e
375  ! not tested as well!
376 
377  integer(kind=intType) :: parent, child, n
378  real(kind=realtype) :: prichild, prichildp1
379 
380  type(kdtree2_result) :: etmp
381 
382  if (.true.) then
383  n = a%heap_size
384  if (n .ge. 1) then
385  parent = 1
386  child = 2
387 
388  loop: do while (child .le. n)
389  prichild = a%elems(child)%dis
390 
391  !
392  ! posibly child+1 has higher priority, and if
393  ! so, get it, and increment child.
394  !
395 
396  if (child .lt. n) then
397  prichildp1 = a%elems(child + 1)%dis
398  if (prichild .lt. prichildp1) then
399  child = child + 1
400  prichild = prichildp1
401  end if
402  end if
403 
404  if (dis .ge. prichild) then
405  exit loop
406  ! we have a proper place for our new element,
407  ! bigger than either children's priority.
408  else
409  ! move child into parent.
410  a%elems(parent) = a%elems(child)
411  parent = child
412  child = 2 * parent
413  end if
414  end do loop
415  a%elems(parent)%dis = dis
416  a%elems(parent)%idx = idx
417  pq_replace_max = a%elems(1)%dis
418  else
419  a%elems(1)%dis = dis
420  a%elems(1)%idx = idx
421  pq_replace_max = dis
422  end if
423  else
424  !
425  ! slower version using elementary pop and push operations.
426  !
427  call pq_extract_max(a, etmp)
428  etmp%dis = dis
429  etmp%idx = idx
430  pq_replace_max = pq_insert(a, dis, idx)
431  end if
432  return
433  end function pq_replace_max
434 
435  subroutine pq_delete(a, i)
436  implicit none
437  !
438  ! delete item with index 'i'
439  !
440  type(pq), pointer :: a
441  integer(kind=intType) :: i
442 
443  if ((i .lt. 1) .or. (i .gt. a%heap_size)) then
444  write (*, *) 'PQ_DELETE: error, attempt to remove out of bounds element.'
445  stop
446  end if
447 
448  ! swap the item to be deleted with the last element
449  ! and shorten heap by one.
450  a%elems(i) = a%elems(a%heap_size)
451  a%heap_size = a%heap_size - 1
452 
453  call heapify(a, i)
454 
455  end subroutine pq_delete
456 
458 
461  use precision
462  ! K-D tree routines in Fortran 90 by Matt Kennel.
463  ! Original program was written in Sather by Steve Omohundro and
464  ! Matt Kennel. Only the Euclidean metric is supported.
465  !
466  !
467  ! This module is identical to 'kdtree', except that the order
468  ! of subscripts is reversed in the data file.
469  ! In otherwords for an embedding of N D-dimensional vectors, the
470  ! data file is here, in natural Fortran order data(1:D, 1:N)
471  ! because Fortran lays out columns first,
472  !
473  ! whereas conventionally (C-style) it is data(1:N,1:D)
474  ! as in the original kdtree module.
475  !
476  !-------------DATA TYPE, CREATION, DELETION---------------------
478  !---------------------------------------------------------------
479  !-------------------SEARCH ROUTINES-----------------------------
481  ! Return fixed number of nearest neighbors around arbitrary vector,
482  ! or extant point in dataset, with decorrelation window.
483  !
485  ! Return points within a fixed ball of arb vector/extant point
486  !
487  public :: kdtree2_sort_results
488  ! Sort, in order of increasing distance, rseults from above.
489  !
491  ! Count points within a fixed ball of arb vector/extant point
492  !
494  ! brute force of kdtree2_[n|r]_nearest
495  !----------------------------------------------------------------
496 
497  integer(kind=intType), parameter :: bucket_size = 12
498  ! The maximum number of points to keep in a terminal node.
499 
500  type interval
501  real(kind=realtype) :: lower, upper
502  end type interval
503 
504  type :: tree_node
505  ! an internal tree node
506  private
507  integer(kind=intType) :: cut_dim
508  ! the dimension to cut
509  real(kind=realtype) :: cut_val
510  ! where to cut the dimension
511  real(kind=realtype) :: cut_val_left, cut_val_right
512  ! improved cutoffs knowing the spread in child boxes.
513  integer(kind=intType) :: l, u
514  type(tree_node), pointer :: left, right
515  type(interval), pointer :: box(:) => null()
516  ! child pointers
517  ! Points included in this node are indexes[k] with k \in [l,u]
518 
519  end type tree_node
520 
521  type :: kdtree2
522  ! Global information about the tree, one per tree
523  integer(kind=intType) :: dimen = 0, n = 0
524  ! dimensionality and total # of points
525  real(kind=realtype), pointer :: the_data(:, :) => null()
526  ! pointer to the actual data array
527  !
528  ! IMPORTANT NOTE: IT IS DIMENSIONED the_data(1:d,1:N)
529  ! which may be opposite of what may be conventional.
530  ! This is, because in Fortran, the memory layout is such that
531  ! the first dimension is in sequential order. Hence, with
532  ! (1:d,1:N), all components of the vector will be in consecutive
533  ! memory locations. The search time is dominated by the
534  ! evaluation of distances in the terminal nodes. Putting all
535  ! vector components in consecutive memory location improves
536  ! memory cache locality, and hence search speed, and may enable
537  ! vectorization on some processors and compilers.
538 
539  integer(kind=intType), pointer :: ind(:) => null()
540  ! permuted index into the data, so that indexes[l..u] of some
541  ! bucket represent the indexes of the actual points in that
542  ! bucket.
543  logical :: sort = .false.
544  ! do we always sort output results?
545  logical :: rearrange = .false.
546  real(kind=realtype), pointer :: rearranged_data(:, :) => null()
547  ! if (rearrange .eqv. .true.) then rearranged_data has been
548  ! created so that rearranged_data(:,i) = the_data(:,ind(i)),
549  ! permitting search to use more cache-friendly rearranged_data, at
550  ! some initial computation and storage cost.
551  type(tree_node), pointer :: root => null()
552  ! root pointer of the tree
553  end type kdtree2
554 
556  !
557  ! One of these is created for each search.
558  !
559  private
560  !
561  ! Many fields are copied from the tree structure, in order to
562  ! speed up the search.
563  !
564  integer(kind=intType) :: dimen
565  integer(kind=intType) :: nn, nfound
566  real(kind=realtype) :: ballsize
567  integer(kind=intType) :: centeridx = 999, correltime = 9999
568  ! exclude points within 'correltime' of 'centeridx', iff centeridx >= 0
569  integer(kind=intType) :: nalloc ! how much allocated for results(:)?
570  logical :: rearrange ! are the data rearranged or original?
571  ! did the # of points found overflow the storage provided?
572  logical :: overflow
573  real(kind=realtype), pointer :: qv(:) ! query vector
574  type(kdtree2_result), pointer :: results(:) ! results
575  type(pq) :: pq
576  real(kind=realtype), pointer :: data(:, :) ! temp pointer to data
577  integer(kind=intType), pointer :: ind(:) ! temp pointer to indexes
578  end type tree_search_record
579 
580  private
581  ! everything else is private.
582 
583  type(tree_search_record), save, target :: sr ! A GLOBAL VARIABLE for search
584 
585 contains
586 
587  function kdtree2_create(input_data, dim, sort, rearrange) result(mr)
588  implicit none
589  !
590  ! create the actual tree structure, given an input array of data.
591  !
592  ! Note, input data is input_data(1:d,1:N), NOT the other way around.
593  ! THIS IS THE REVERSE OF THE PREVIOUS VERSION OF THIS MODULE.
594  ! The reason for it is cache friendliness, improving performance.
595  !
596  ! Optional arguments: If 'dim' is specified, then the tree
597  ! will only search the first 'dim' components
598  ! of input_data, otherwise, dim is inferred
599  ! from SIZE(input_data,1).
600  !
601  ! if sort .eqv. .true. then output results
602  ! will be sorted by increasing distance.
603  ! default=.false., as it is faster to not sort.
604  !
605  ! if rearrange .eqv. .true. then an internal
606  ! copy of the data, rearranged by terminal node,
607  ! will be made for cache friendliness.
608  ! default=.true., as it speeds searches, but
609  ! building takes longer, and extra memory is used.
610  !
611  ! .. Function Return Cut_value ..
612  type(kdtree2), pointer :: mr
613  integer(kind=intType), intent(in), optional :: dim
614  logical, intent(in), optional :: sort
615  logical, intent(in), optional :: rearrange
616  ! ..
617  ! .. Array Arguments ..
618  real(kind=realtype), target :: input_data(:, :)
619  !
620  integer(kind=intType) :: i
621  ! ..
622  allocate (mr)
623  mr%the_data => input_data
624  ! pointer assignment
625 
626  if (present(dim)) then
627  mr%dimen = dim
628  else
629  mr%dimen = size(input_data, 1)
630  end if
631  mr%n = size(input_data, 2)
632 
633  call build_tree(mr)
634 
635  if (present(sort)) then
636  mr%sort = sort
637  else
638  mr%sort = .false.
639  end if
640 
641  if (present(rearrange)) then
642  mr%rearrange = rearrange
643  else
644  mr%rearrange = .true.
645  end if
646 
647  if (mr%rearrange) then
648  allocate (mr%rearranged_data(mr%dimen, mr%n))
649  do i = 1, mr%n
650  mr%rearranged_data(:, i) = mr%the_data(:, &
651  mr%ind(i))
652  end do
653  else
654  nullify (mr%rearranged_data)
655  end if
656 
657  end function kdtree2_create
658 
659  subroutine build_tree(tp)
660  implicit none
661  type(kdtree2), pointer :: tp
662  ! ..
663  integer(kind=intType) :: j
664  type(tree_node), pointer :: dummy => null()
665  ! ..
666  allocate (tp%ind(tp%n))
667  forall (j=1:tp%n)
668  tp%ind(j) = j
669  end forall
670  tp%root => build_tree_for_range(tp, 1, tp%n, dummy)
671  end subroutine build_tree
672 
673  recursive function build_tree_for_range(tp, l, u, parent) result(res)
674  use constants
675  implicit none
676  ! .. Function Return Cut_value ..
677  type(tree_node), pointer :: res
678  ! ..
679  ! .. Structure Arguments ..
680  type(kdtree2), pointer :: tp
681  type(tree_node), pointer :: parent
682  ! ..
683  ! .. Scalar Arguments ..
684  integer(kind=intType), intent(In) :: l, u
685  ! ..
686  ! .. Local Scalars ..
687  integer(kind=intType) :: i, c, m, dimen, idim
688  logical :: recompute
689  real(kind=realtype) :: average, left, right, coorspread(tp%dimen), tmp
690 
691 !!$ If (.False.) Then
692 !!$ If ((l .Lt. 1) .Or. (l .Gt. tp%n)) Then
693 !!$ Stop 'illegal L value in build_tree_for_range'
694 !!$ End If
695 !!$ If ((u .Lt. 1) .Or. (u .Gt. tp%n)) Then
696 !!$ Stop 'illegal u value in build_tree_for_range'
697 !!$ End If
698 !!$ If (u .Lt. l) Then
699 !!$ Stop 'U is less than L, thats illegal.'
700 !!$ End If
701 !!$ Endif
702 !!$
703  ! first compute min and max
704  dimen = tp%dimen
705  allocate (res)
706  allocate (res%box(dimen))
707 
708  ! First, compute an APPROXIMATE bounding box of all points associated with this node.
709  if (u < l) then
710  ! no points in this box
711  nullify (res)
712  return
713  end if
714 
715  if ((u - l) <= bucket_size) then
716  !
717  ! always compute true bounding box for terminal nodes.
718  !
719  do i = 1, dimen
720  call spread_in_coordinate(tp, i, l, u, res%box(i))
721  end do
722  res%cut_dim = 0
723  res%cut_val = 0.0
724  res%l = l
725  res%u = u
726  res%left => null()
727  res%right => null()
728  else
729  !
730  ! modify approximate bounding box. This will be an
731  ! overestimate of the true bounding box, as we are only recomputing
732  ! the bounding box for the dimension that the parent split on.
733  !
734  ! Going to a true bounding box computation would significantly
735  ! increase the time necessary to build the tree, and usually
736  ! has only a very small difference. This box is not used
737  ! for searching but only for deciding which coordinate to split on.
738  !
739  do i = 1, dimen
740  recompute = .true.
741  if (associated(parent)) then
742  if (i .ne. parent%cut_dim) then
743  recompute = .false.
744  end if
745  end if
746  if (recompute) then
747  call spread_in_coordinate(tp, i, l, u, res%box(i))
748  else
749  res%box(i) = parent%box(i)
750  end if
751  end do
752 
753  !
754  ! c is the identity of which coordinate has the greatest spread.
755  !
756 
757  coorspread = res%box(1:dimen)%upper - res%box(1:dimen)%lower
758 
759  tmp = -one
760  do i = 1, dimen
761  if (coorspread(i) > tmp) then
762  tmp = coorspread(i)
763  c = i
764  end if
765  end do
766 
767  if (.true.) then
768  ! select exact median to have fully balanced tree.
769  m = (l + u) / 2
770  call select_on_coordinate(tp%the_data, tp%ind, c, m, l, u)
771  else
772  !
773  ! select point halfway between min and max, as per A. Moore,
774  ! who says this helps in some degenerate cases, or
775  ! actual arithmetic average.
776  !
777  if (.true.) then
778  ! actually compute average
779  average = sum(tp%the_data(c, tp%ind(l:u))) / real(u - l + 1, kind=realtype)
780  else
781  average = (res%box(c)%upper + res%box(c)%lower) / 2.0
782  end if
783 
784  res%cut_val = average
785  m = select_on_coordinate_value(tp%the_data, tp%ind, c, average, l, u)
786  end if
787 
788  ! moves indexes around
789  res%cut_dim = c
790  res%l = l
791  res%u = u
792  ! res%cut_val = tp%the_data(c,tp%ind(m))
793 
794  res%left => build_tree_for_range(tp, l, m, res)
795  res%right => build_tree_for_range(tp, m + 1, u, res)
796 
797  if (associated(res%right) .eqv. .false.) then
798  res%box = res%left%box
799  res%cut_val_left = res%left%box(c)%upper
800  res%cut_val = res%cut_val_left
801  elseif (associated(res%left) .eqv. .false.) then
802  res%box = res%right%box
803  res%cut_val_right = res%right%box(c)%lower
804  res%cut_val = res%cut_val_right
805  else
806  res%cut_val_right = res%right%box(c)%lower
807  res%cut_val_left = res%left%box(c)%upper
808  res%cut_val = (res%cut_val_left + res%cut_val_right) / 2
809 
810  ! now remake the true bounding box for self.
811  ! Since we are taking unions (in effect) of a tree structure,
812  ! this is much faster than doing an exhaustive
813  ! search over all points
814  do idim = 1, dimen
815  left = res%left%box(idim)%upper
816  right = res%right%box(idim)%upper
817  res%box(idim)%upper = max(left, right)
818 
819  left = res%left%box(idim)%lower
820  right = res%right%box(idim)%lower
821 
822  res%box(idim)%lower = min(left, right)
823  end do
824  ! res%box%upper = max(res%left%box%upper,res%right%box%upper)
825  ! res%box%lower = min(res%left%box%lower,res%right%box%lower)
826  end if
827  end if
828  end function build_tree_for_range
829 
830  integer(kind=intType) function select_on_coordinate_value(v, ind, c, alpha, li, ui) &
831  result(res)
832  implicit none
833  ! Move elts of ind around between l and u, so that all points
834  ! <= than alpha (in c cooordinate) are first, and then
835  ! all points > alpha are second.
836 
837  !
838  ! Algorithm (matt kennel).
839  !
840  ! Consider the list as having three parts: on the left,
841  ! the points known to be <= alpha. On the right, the points
842  ! known to be > alpha, and in the middle, the currently unknown
843  ! points. The algorithm is to scan the unknown points, starting
844  ! from the left, and swapping them so that they are added to
845  ! the left stack or the right stack, as appropriate.
846  !
847  ! The algorithm finishes when the unknown stack is empty.
848  !
849  ! .. Scalar Arguments ..
850  integer(kind=intType), intent(In) :: c, li, ui
851  real(kind=realtype), intent(in) :: alpha
852  ! ..
853  real(kind=realtype) :: v(1:, 1:)
854  integer(kind=intType) :: ind(1:)
855  integer(kind=intType) :: tmp
856  ! ..
857  integer(kind=intType) :: lb, rb
858  !
859  ! The points known to be <= alpha are in
860  ! [l,lb-1]
861  !
862  ! The points known to be > alpha are in
863  ! [rb+1,u].
864  !
865  ! Therefore we add new points into lb or
866  ! rb as appropriate. When lb=rb
867  ! we are done. We return the location of the last point <= alpha.
868  !
869  !
870  lb = li; rb = ui
871 
872  do while (lb < rb)
873  if (v(c, ind(lb)) <= alpha) then
874  ! it is good where it is.
875  lb = lb + 1
876  else
877  ! swap it with rb.
878  tmp = ind(lb); ind(lb) = ind(rb); ind(rb) = tmp
879  rb = rb - 1
880  end if
881  end do
882 
883  ! now lb .eq. ub
884  if (v(c, ind(lb)) <= alpha) then
885  res = lb
886  else
887  res = lb - 1
888  end if
889 
890  end function select_on_coordinate_value
891 
892  subroutine select_on_coordinate(v, ind, c, k, li, ui)
893  implicit none
894  ! Move elts of ind around between l and u, so that the kth
895  ! element
896  ! is >= those below, <= those above, in the coordinate c.
897  ! .. Scalar Arguments ..
898  integer(kind=intType), intent(In) :: c, k, li, ui
899  ! ..
900  integer(kind=intType) :: i, l, m, s, t, u
901  ! ..
902  real(kind=realtype) :: v(:, :)
903  integer(kind=intType) :: ind(:)
904  ! ..
905  l = li
906  u = ui
907  do while (l < u)
908  t = ind(l)
909  m = l
910  do i = l + 1, u
911  if (v(c, ind(i)) < v(c, t)) then
912  m = m + 1
913  s = ind(m)
914  ind(m) = ind(i)
915  ind(i) = s
916  end if
917  end do
918  s = ind(l)
919  ind(l) = ind(m)
920  ind(m) = s
921  if (m <= k) l = m + 1
922  if (m >= k) u = m - 1
923  end do
924  end subroutine select_on_coordinate
925 
926  subroutine spread_in_coordinate(tp, c, l, u, interv)
927 
928  implicit none
929 
930  ! the spread in coordinate 'c', between l and u.
931  !
932  ! Return lower bound in 'smin', and upper in 'smax',
933  ! ..
934  ! .. Structure Arguments ..
935  type(kdtree2), pointer :: tp
936  type(interval), intent(out) :: interv
937  ! ..
938  ! .. Scalar Arguments ..
939  integer(kind=intType), intent(In) :: c, l, u
940  ! ..
941  ! .. Local Scalars ..
942  real(kind=realtype) :: last, lmax, lmin, t, smin, smax
943  integer(kind=intType) :: i, ulocal
944  ! ..
945  ! .. Local Arrays ..
946  real(kind=realtype), pointer :: v(:, :)
947  integer(kind=intType), pointer :: ind(:)
948 
949  v => tp%the_data(1:, 1:)
950  ind => tp%ind(1:)
951  smin = v(c, ind(l))
952  smax = smin
953 
954  ulocal = u
955 
956  do i = l + 2, ulocal, 2
957  lmin = v(c, ind(i - 1))
958  lmax = v(c, ind(i))
959  if (lmin > lmax) then
960  t = lmin
961  lmin = lmax
962  lmax = t
963  end if
964  if (smin > lmin) smin = lmin
965  if (smax < lmax) smax = lmax
966  end do
967  if (i == ulocal + 1) then
968  last = v(c, ind(ulocal))
969  if (smin > last) smin = last
970  if (smax < last) smax = last
971  end if
972 
973  interv%lower = smin
974  interv%upper = smax
975 
976  end subroutine spread_in_coordinate
977 
978  subroutine kdtree2destroy(tp)
979  implicit none
980  ! Deallocates all memory for the tree, except input data matrix
981  ! .. Structure Arguments ..
982  type(kdtree2), pointer :: tp
983  ! ..
984  call destroy_node(tp%root)
985 
986  deallocate (tp%ind)
987  nullify (tp%ind)
988 
989  if (tp%rearrange) then
990  deallocate (tp%rearranged_data)
991  nullify (tp%rearranged_data)
992  end if
993 
994  deallocate (tp)
995  return
996 
997  contains
998  recursive subroutine destroy_node(np)
999  implicit none
1000  ! .. Structure Arguments ..
1001  type(tree_node), pointer :: np
1002  ! ..
1003  ! .. Intrinsic Functions ..
1004  intrinsic ASSOCIATED
1005  ! ..
1006  if (associated(np%left)) then
1007  call destroy_node(np%left)
1008  nullify (np%left)
1009  end if
1010  if (associated(np%right)) then
1011  call destroy_node(np%right)
1012  nullify (np%right)
1013  end if
1014  if (associated(np%box)) deallocate (np%box)
1015  deallocate (np)
1016  return
1017 
1018  end subroutine destroy_node
1019 
1020  end subroutine kdtree2destroy
1021 
1022  subroutine kdtree2_n_nearest(tp, qv, nn, results)
1023  implicit none
1024  ! Find the 'nn' vectors in the tree nearest to 'qv' in euclidean norm
1025  ! returning their indexes and distances in 'indexes' and 'distances'
1026  ! arrays already allocated passed to this subroutine.
1027  type(kdtree2), pointer :: tp
1028  real(kind=realtype), target, intent(In) :: qv(:)
1029  integer(kind=intType), intent(In) :: nn
1030  type(kdtree2_result), target :: results(:)
1031 
1032  sr%ballsize = huge(1.0)
1033  sr%qv => qv
1034  sr%nn = nn
1035  sr%nfound = 0
1036  sr%centeridx = -1
1037  sr%correltime = 0
1038  sr%overflow = .false.
1039 
1040  sr%results => results
1041 
1042  sr%nalloc = nn ! will be checked
1043 
1044  sr%ind => tp%ind
1045  sr%rearrange = tp%rearrange
1046  if (tp%rearrange) then
1047  sr%Data => tp%rearranged_data
1048  else
1049  sr%Data => tp%the_data
1050  end if
1051  sr%dimen = tp%dimen
1052 
1053  call validate_query_storage(nn)
1054  sr%pq = pq_create(results)
1055 
1056  call search(tp%root)
1057 
1058  if (tp%sort) then
1059  call kdtree2_sort_results(nn, results)
1060  end if
1061  ! deallocate(sr%pqp)
1062  return
1063  end subroutine kdtree2_n_nearest
1064 
1065  subroutine kdtree2_n_nearest_around_point(tp, idxin, correltime, nn, results)
1066  implicit none
1067  ! Find the 'nn' vectors in the tree nearest to point 'idxin',
1068  ! with correlation window 'correltime', returing results in
1069  ! results(:), which must be pre-allocated upon entry.
1070  type(kdtree2), pointer :: tp
1071  integer(kind=intType), intent(In) :: idxin, correltime, nn
1072  type(kdtree2_result), target :: results(:)
1073 
1074  allocate (sr%qv(tp%dimen))
1075  sr%qv = tp%the_data(:, idxin) ! copy the vector
1076  sr%ballsize = huge(1.0) ! the largest real(kind=realType) number
1077  sr%centeridx = idxin
1078  sr%correltime = correltime
1079 
1080  sr%nn = nn
1081  sr%nfound = 0
1082 
1083  sr%dimen = tp%dimen
1084  sr%nalloc = nn
1085 
1086  sr%results => results
1087 
1088  sr%ind => tp%ind
1089  sr%rearrange = tp%rearrange
1090 
1091  if (sr%rearrange) then
1092  sr%Data => tp%rearranged_data
1093  else
1094  sr%Data => tp%the_data
1095  end if
1096 
1097  call validate_query_storage(nn)
1098  sr%pq = pq_create(results)
1099 
1100  call search(tp%root)
1101 
1102  if (tp%sort) then
1103  call kdtree2_sort_results(nn, results)
1104  end if
1105  deallocate (sr%qv)
1106  return
1107  end subroutine kdtree2_n_nearest_around_point
1108 
1109  subroutine kdtree2_r_nearest(tp, qv, r2, nfound, nalloc, results)
1110  implicit none
1111  ! find the nearest neighbors to point 'idxin', within SQUARED
1112  ! Euclidean distance 'r2'. Upon ENTRY, nalloc must be the
1113  ! size of memory allocated for results(1:nalloc). Upon
1114  ! EXIT, nfound is the number actually found within the ball.
1115  !
1116  ! Note that if nfound .gt. nalloc then more neighbors were found
1117  ! than there were storage to store. The resulting list is NOT
1118  ! the smallest ball inside norm r^2
1119  !
1120  ! Results are NOT sorted unless tree was created with sort option.
1121  type(kdtree2), pointer :: tp
1122  real(kind=realtype), target, intent(In) :: qv(:)
1123  real(kind=realtype), intent(in) :: r2
1124  integer(kind=intType), intent(out) :: nfound
1125  integer(kind=intType), intent(In) :: nalloc
1126  type(kdtree2_result), target :: results(:)
1127 
1128  !
1129  sr%qv => qv
1130  sr%ballsize = r2
1131  sr%nn = 0 ! flag for fixed ball search
1132  sr%nfound = 0
1133  sr%centeridx = -1
1134  sr%correltime = 0
1135 
1136  sr%results => results
1137 
1138  call validate_query_storage(nalloc)
1139  sr%nalloc = nalloc
1140  sr%overflow = .false.
1141  sr%ind => tp%ind
1142  sr%rearrange = tp%rearrange
1143 
1144  if (tp%rearrange) then
1145  sr%Data => tp%rearranged_data
1146  else
1147  sr%Data => tp%the_data
1148  end if
1149  sr%dimen = tp%dimen
1150 
1151  !
1152  !sr%dsl = Huge(sr%dsl) ! set to huge positive values
1153  !sr%il = -1 ! set to invalid indexes
1154  !
1155 
1156  call search(tp%root)
1157  nfound = sr%nfound
1158  if (sr%overflow) then
1159  ! Sorting will cause an error if we have overflowed.
1160  return
1161  end if
1162 
1163  if (tp%sort) then
1164  call kdtree2_sort_results(nfound, results)
1165  end if
1166 
1167  end subroutine kdtree2_r_nearest
1168 
1169  subroutine kdtree2_r_nearest_around_point(tp, idxin, correltime, r2, &
1170  nfound, nalloc, results)
1171  implicit none
1172  !
1173  ! Like kdtree2_r_nearest, but around a point 'idxin' already existing
1174  ! in the data set.
1175  !
1176  ! Results are NOT sorted unless tree was created with sort option.
1177  !
1178  type(kdtree2), pointer :: tp
1179  integer(kind=intType), intent(In) :: idxin, correltime, nalloc
1180  real(kind=realtype), intent(in) :: r2
1181  integer(kind=intType), intent(out) :: nfound
1182  type(kdtree2_result), target :: results(:)
1183  ! ..
1184  ! .. Intrinsic Functions ..
1185  intrinsic huge
1186  ! ..
1187  allocate (sr%qv(tp%dimen))
1188  sr%qv = tp%the_data(:, idxin) ! copy the vector
1189  sr%ballsize = r2
1190  sr%nn = 0 ! flag for fixed r search
1191  sr%nfound = 0
1192  sr%centeridx = idxin
1193  sr%correltime = correltime
1194 
1195  sr%results => results
1196 
1197  sr%nalloc = nalloc
1198  sr%overflow = .false.
1199 
1200  call validate_query_storage(nalloc)
1201 
1202  ! sr%dsl = HUGE(sr%dsl) ! set to huge positive values
1203  ! sr%il = -1 ! set to invalid indexes
1204 
1205  sr%ind => tp%ind
1206  sr%rearrange = tp%rearrange
1207 
1208  if (tp%rearrange) then
1209  sr%Data => tp%rearranged_data
1210  else
1211  sr%Data => tp%the_data
1212  end if
1213  sr%rearrange = tp%rearrange
1214  sr%dimen = tp%dimen
1215 
1216  !
1217  !sr%dsl = Huge(sr%dsl) ! set to huge positive values
1218  !sr%il = -1 ! set to invalid indexes
1219  !
1220 
1221  call search(tp%root)
1222  nfound = sr%nfound
1223  if (tp%sort) then
1224  call kdtree2_sort_results(nfound, results)
1225  end if
1226 
1227  if (sr%overflow) then
1228  write (*, *) 'KDTREE_TRANS: warning! return from kdtree2_r_nearest found more neighbors'
1229  write (*, *) 'KDTREE_TRANS: than storage was provided for. Answer is NOT smallest ball'
1230  write (*, *) 'KDTREE_TRANS: with that number of neighbors! I.e. it is wrong.'
1231  end if
1232 
1233  deallocate (sr%qv)
1234  return
1235  end subroutine kdtree2_r_nearest_around_point
1236 
1237  function kdtree2_r_count(tp, qv, r2) result(nfound)
1238  implicit none
1239  ! Count the number of neighbors within square distance 'r2'.
1240  type(kdtree2), pointer :: tp
1241  real(kind=realtype), target, intent(In) :: qv(:)
1242  real(kind=realtype), intent(in) :: r2
1243  integer(kind=intType) :: nfound
1244  ! ..
1245  ! .. Intrinsic Functions ..
1246  intrinsic huge
1247  ! ..
1248  sr%qv => qv
1249  sr%ballsize = r2
1250 
1251  sr%nn = 0 ! flag for fixed r search
1252  sr%nfound = 0
1253  sr%centeridx = -1
1254  sr%correltime = 0
1255 
1256  nullify (sr%results) ! for some reason, FTN 95 chokes on '=> null()'
1257 
1258  sr%nalloc = 0 ! we do not allocate any storage but that's OK
1259  ! for counting.
1260  sr%ind => tp%ind
1261  sr%rearrange = tp%rearrange
1262  if (tp%rearrange) then
1263  sr%Data => tp%rearranged_data
1264  else
1265  sr%Data => tp%the_data
1266  end if
1267  sr%dimen = tp%dimen
1268 
1269  !
1270  !sr%dsl = Huge(sr%dsl) ! set to huge positive values
1271  !sr%il = -1 ! set to invalid indexes
1272  !
1273  sr%overflow = .false.
1274 
1275  call search(tp%root)
1276 
1277  nfound = sr%nfound
1278 
1279  return
1280  end function kdtree2_r_count
1281 
1282  function kdtree2_r_count_around_point(tp, idxin, correltime, r2) &
1283  result(nfound)
1284  implicit none
1285  ! Count the number of neighbors within square distance 'r2' around
1286  ! point 'idxin' with decorrelation time 'correltime'.
1287  !
1288  type(kdtree2), pointer :: tp
1289  integer(kind=intType), intent(In) :: correltime, idxin
1290  real(kind=realtype), intent(in) :: r2
1291  integer(kind=intType) :: nfound
1292  ! ..
1293  ! ..
1294  ! .. Intrinsic Functions ..
1295  intrinsic huge
1296  ! ..
1297  allocate (sr%qv(tp%dimen))
1298  sr%qv = tp%the_data(:, idxin)
1299  sr%ballsize = r2
1300 
1301  sr%nn = 0 ! flag for fixed r search
1302  sr%nfound = 0
1303  sr%centeridx = idxin
1304  sr%correltime = correltime
1305  nullify (sr%results)
1306 
1307  sr%nalloc = 0 ! we do not allocate any storage but that's OK
1308  ! for counting.
1309 
1310  sr%ind => tp%ind
1311  sr%rearrange = tp%rearrange
1312 
1313  if (sr%rearrange) then
1314  sr%Data => tp%rearranged_data
1315  else
1316  sr%Data => tp%the_data
1317  end if
1318  sr%dimen = tp%dimen
1319 
1320  !
1321  !sr%dsl = Huge(sr%dsl) ! set to huge positive values
1322  !sr%il = -1 ! set to invalid indexes
1323  !
1324  sr%overflow = .false.
1325 
1326  call search(tp%root)
1327 
1328  nfound = sr%nfound
1329 
1330  return
1331  end function kdtree2_r_count_around_point
1332 
1333  subroutine validate_query_storage(n)
1334  implicit none
1335  !
1336  ! make sure we have enough storage for n
1337  !
1338  integer(kind=intType), intent(in) :: n
1339 
1340  if (size(sr%results, 1) .lt. n) then
1341  write (*, *) 'KDTREE_TRANS: you did not provide enough storage for results(1:n)'
1342  stop
1343  return
1344  end if
1345 
1346  return
1347  end subroutine validate_query_storage
1348 
1349  function square_distance(d, iv, qv) result(res)
1350  implicit none
1351  ! distance between iv[1:n] and qv[1:n]
1352  ! .. Function Return Value ..
1353  ! re-implemented to improve vectorization.
1354  real(kind=realtype) :: res
1355  ! ..
1356  ! ..
1357  ! .. Scalar Arguments ..
1358  integer(kind=intType) :: d
1359  ! ..
1360  ! .. Array Arguments ..
1361  real(kind=realtype) :: iv(:), qv(:)
1362  ! ..
1363  ! ..
1364  res = sum((iv(1:d) - qv(1:d))**2)
1365  end function square_distance
1366 
1367  recursive subroutine search(node)
1368  implicit none
1369  !
1370  ! This is the innermost core routine of the kd-tree search. Along
1371  ! with "process_terminal_node", it is the performance bottleneck.
1372  !
1373  ! This version uses a logically complete secondary search of
1374  ! "box in bounds", whether the sear
1375  !
1376  type(tree_node), pointer :: node
1377  ! ..
1378  type(tree_node), pointer :: ncloser, nfarther
1379  !
1380  integer(kind=intType) :: cut_dim, i
1381  ! ..
1382  real(kind=realtype) :: qval, dis
1383  real(kind=realtype) :: ballsize
1384  real(kind=realtype), pointer :: qv(:)
1385  type(interval), pointer :: box(:)
1386 
1387  if ((associated(node%left) .and. associated(node%right)) .eqv. .false.) then
1388  ! we are on a terminal node
1389  if (sr%nn .eq. 0) then
1390  call process_terminal_node_fixedball(node)
1391  else
1392  call process_terminal_node(node)
1393  end if
1394  else
1395  ! we are not on a terminal node
1396  qv => sr%qv(1:)
1397  cut_dim = node%cut_dim
1398  qval = qv(cut_dim)
1399 
1400  if (qval < node%cut_val) then
1401  ncloser => node%left
1402  nfarther => node%right
1403  dis = (node%cut_val_right - qval)**2
1404  ! extra = node%cut_val - qval
1405  else
1406  ncloser => node%right
1407  nfarther => node%left
1408  dis = (node%cut_val_left - qval)**2
1409  ! extra = qval- node%cut_val_left
1410  end if
1411 
1412  if (associated(ncloser)) call search(ncloser)
1413 
1414  ! we may need to search the second node.
1415  if (associated(nfarther)) then
1416  ballsize = sr%ballsize
1417  ! dis=extra**2
1418  if (dis <= ballsize) then
1419  !
1420  ! we do this separately as going on the first cut dimen is often
1421  ! a good idea.
1422  ! note that if extra**2 < sr%ballsize, then the next
1423  ! check will also be false.
1424  !
1425  box => node%box(1:)
1426  do i = 1, sr%dimen
1427  if (i .ne. cut_dim) then
1428  dis = dis + dis2_from_bnd(qv(i), box(i)%lower, box(i)%upper)
1429  if (dis > ballsize) then
1430  return
1431  end if
1432  end if
1433  end do
1434 
1435  !
1436  ! if we are still here then we need to search mroe.
1437  !
1438  call search(nfarther)
1439  end if
1440  end if
1441  end if
1442  end subroutine search
1443 
1444  real(kind=realtype) function dis2_from_bnd(x, amin, amax) result(res)
1445  implicit none
1446  real(kind=realtype), intent(in) :: x, amin, amax
1447 
1448  if (x > amax) then
1449  res = (x - amax)**2;
1450  return
1451  else
1452  if (x < amin) then
1453  res = (amin - x)**2;
1454  return
1455  else
1456  res = 0.0
1457  return
1458  end if
1459  end if
1460  return
1461  end function dis2_from_bnd
1462 
1463  logical function box_in_search_range(node, sr) result(res)
1464  implicit none
1465  !
1466  ! Return the distance from 'qv' to the CLOSEST corner of node's
1467  ! bounding box
1468  ! for all coordinates outside the box. Coordinates inside the box
1469  ! contribute nothing to the distance.
1470  !
1471  type(tree_node), pointer :: node
1472  type(tree_search_record), pointer :: sr
1473 
1474  integer(kind=intType) :: dimen, i
1475  real(kind=realtype) :: dis, ballsize
1476  real(kind=realtype) :: l, u
1477 
1478  dimen = sr%dimen
1479  ballsize = sr%ballsize
1480  dis = 0.0
1481  res = .true.
1482  do i = 1, dimen
1483  l = node%box(i)%lower
1484  u = node%box(i)%upper
1485  dis = dis + (dis2_from_bnd(sr%qv(i), l, u))
1486  if (dis > ballsize) then
1487  res = .false.
1488  return
1489  end if
1490  end do
1491  res = .true.
1492  return
1493  end function box_in_search_range
1494 
1495  subroutine process_terminal_node(node)
1496  implicit none
1497  !
1498  ! Look for actual near neighbors in 'node', and update
1499  ! the search results on the sr data structure.
1500  !
1501  type(tree_node), pointer :: node
1502  !
1503  real(kind=realtype), pointer :: qv(:)
1504  integer(kind=intType), pointer :: ind(:)
1505  real(kind=realtype), pointer :: data(:, :)
1506  !
1507  integer(kind=intType) :: dimen, i, indexofi, k, centeridx, correltime
1508  real(kind=realtype) :: ballsize, sd, newpri
1509  logical :: rearrange
1510  type(pq), pointer :: pqp
1511  !
1512  ! copy values from sr to local variables
1513  !
1514  !
1515  ! Notice, making local pointers with an EXPLICIT lower bound
1516  ! seems to generate faster code.
1517  ! why? I don't know.
1518  qv => sr%qv(1:)
1519  pqp => sr%pq
1520  dimen = sr%dimen
1521  ballsize = sr%ballsize
1522  rearrange = sr%rearrange
1523  ind => sr%ind(1:)
1524  data => sr%Data(1:, 1:)
1525  centeridx = sr%centeridx
1526  correltime = sr%correltime
1527 
1528  ! doing_correl = (centeridx >= 0) ! Do we have a decorrelation window?
1529  ! include_point = .true. ! by default include all points
1530  ! search through terminal bucket.
1531 
1532  mainloop: do i = node%l, node%u
1533  if (rearrange) then
1534  sd = 0.0
1535  do k = 1, dimen
1536  sd = sd + (data(k, i) - qv(k))**2
1537  if (sd > ballsize) cycle mainloop
1538  end do
1539  indexofi = ind(i) ! only read it if we have not broken out
1540  else
1541  indexofi = ind(i)
1542  sd = 0.0
1543  do k = 1, dimen
1544  sd = sd + (data(k, indexofi) - qv(k))**2
1545  if (sd > ballsize) cycle mainloop
1546  end do
1547  end if
1548 
1549  if (centeridx > 0) then ! doing correlation interval?
1550  if (abs(indexofi - centeridx) < correltime) cycle mainloop
1551  end if
1552 
1553  !
1554  ! two choices for any point. The list so far is either undersized,
1555  ! or it is not.
1556  !
1557  ! If it is undersized, then add the point and its distance
1558  ! unconditionally. If the point added fills up the working
1559  ! list then set the sr%ballsize, maximum distance bound (largest distance on
1560  ! list) to be that distance, instead of the initialized +infinity.
1561  !
1562  ! If the running list is full size, then compute the
1563  ! distance but break out immediately if it is larger
1564  ! than sr%ballsize, "best squared distance" (of the largest element),
1565  ! as it cannot be a good neighbor.
1566  !
1567  ! Once computed, compare to best_square distance.
1568  ! if it is smaller, then delete the previous largest
1569  ! element and add the new one.
1570 
1571  if (sr%nfound .lt. sr%nn) then
1572  !
1573  ! add this point unconditionally to fill list.
1574  !
1575  sr%nfound = sr%nfound + 1
1576  newpri = pq_insert(pqp, sd, indexofi)
1577  if (sr%nfound .eq. sr%nn) ballsize = newpri
1578  ! we have just filled the working list.
1579  ! put the best square distance to the maximum value
1580  ! on the list, which is extractable from the PQ.
1581 
1582  else
1583  !
1584  ! now, if we get here,
1585  ! we know that the current node has a squared
1586  ! distance smaller than the largest one on the list, and
1587  ! belongs on the list.
1588  ! Hence we replace that with the current one.
1589  !
1590  ballsize = pq_replace_max(pqp, sd, indexofi)
1591  end if
1592  end do mainloop
1593  !
1594  ! Reset sr variables which may have changed during loop
1595  !
1596  sr%ballsize = ballsize
1597 
1598  end subroutine process_terminal_node
1599 
1600  subroutine process_terminal_node_fixedball(node)
1601  implicit none
1602  !
1603  ! Look for actual near neighbors in 'node', and update
1604  ! the search results on the sr data structure, i.e.
1605  ! save all within a fixed ball.
1606  !
1607  type(tree_node), pointer :: node
1608  !
1609  real(kind=realtype), pointer :: qv(:)
1610  integer(kind=intType), pointer :: ind(:)
1611  real(kind=realtype), pointer :: data(:, :)
1612  !
1613  integer(kind=intType) :: nfound
1614  integer(kind=intType) :: dimen, i, indexofi, k
1615  integer(kind=intType) :: centeridx, correltime, nn
1616  real(kind=realtype) :: ballsize, sd
1617  logical :: rearrange
1618 
1619  !
1620  ! copy values from sr to local variables
1621  !
1622  qv => sr%qv(1:)
1623  dimen = sr%dimen
1624  ballsize = sr%ballsize
1625  rearrange = sr%rearrange
1626  ind => sr%ind(1:)
1627  data => sr%Data(1:, 1:)
1628  centeridx = sr%centeridx
1629  correltime = sr%correltime
1630  nn = sr%nn ! number to search for
1631  nfound = sr%nfound
1632 
1633  ! search through terminal bucket.
1634  mainloop: do i = node%l, node%u
1635 
1636  !
1637  ! two choices for any point. The list so far is either undersized,
1638  ! or it is not.
1639  !
1640  ! If it is undersized, then add the point and its distance
1641  ! unconditionally. If the point added fills up the working
1642  ! list then set the sr%ballsize, maximum distance bound (largest distance on
1643  ! list) to be that distance, instead of the initialized +infinity.
1644  !
1645  ! If the running list is full size, then compute the
1646  ! distance but break out immediately if it is larger
1647  ! than sr%ballsize, "best squared distance" (of the largest element),
1648  ! as it cannot be a good neighbor.
1649  !
1650  ! Once computed, compare to best_square distance.
1651  ! if it is smaller, then delete the previous largest
1652  ! element and add the new one.
1653 
1654  ! which index to the point do we use?
1655 
1656  if (rearrange) then
1657  sd = 0.0
1658  do k = 1, dimen
1659  sd = sd + (data(k, i) - qv(k))**2
1660  if (sd > ballsize) cycle mainloop
1661  end do
1662  indexofi = ind(i) ! only read it if we have not broken out
1663  else
1664  indexofi = ind(i)
1665  sd = 0.0
1666  do k = 1, dimen
1667  sd = sd + (data(k, indexofi) - qv(k))**2
1668  if (sd > ballsize) cycle mainloop
1669  end do
1670  end if
1671 
1672  if (centeridx > 0) then ! doing correlation interval?
1673  if (abs(indexofi - centeridx) < correltime) cycle mainloop
1674  end if
1675 
1676  nfound = nfound + 1
1677  if (nfound .gt. sr%nalloc) then
1678  ! oh nuts, we have to add another one to the tree but
1679  ! there isn't enough room.
1680  sr%overflow = .true.
1681  else
1682  sr%results(nfound)%dis = sd
1683  sr%results(nfound)%idx = indexofi
1684  end if
1685  end do mainloop
1686  !
1687  ! Reset sr variables which may have changed during loop
1688  !
1689  sr%nfound = nfound
1690  end subroutine process_terminal_node_fixedball
1691 
1692  subroutine kdtree2_n_nearest_brute_force(tp, qv, nn, results)
1693  implicit none
1694  ! find the 'n' nearest neighbors to 'qv' by exhaustive search.
1695  ! only use this subroutine for testing, as it is SLOW! The
1696  ! whole point of a k-d tree is to avoid doing what this subroutine
1697  ! does.
1698  type(kdtree2), pointer :: tp
1699  real(kind=realtype), intent(In) :: qv(:)
1700  integer(kind=intType), intent(In) :: nn
1701  type(kdtree2_result) :: results(:)
1702 
1703  integer(kind=intType) :: i, j, k
1704  real(kind=realtype), allocatable :: all_distances(:)
1705  ! ..
1706  allocate (all_distances(tp%n))
1707  do i = 1, tp%n
1708  all_distances(i) = square_distance(tp%dimen, qv, tp%the_data(:, i))
1709  end do
1710  ! now find 'n' smallest distances
1711  do i = 1, nn
1712  results(i)%dis = huge(1.0)
1713  results(i)%idx = -1
1714  end do
1715  do i = 1, tp%n
1716  if (all_distances(i) < results(nn)%dis) then
1717  ! insert it somewhere on the list
1718  do j = 1, nn
1719  if (all_distances(i) < results(j)%dis) exit
1720  end do
1721  ! now we know 'j'
1722  do k = nn - 1, j, -1
1723  results(k + 1) = results(k)
1724  end do
1725  results(j)%dis = all_distances(i)
1726  results(j)%idx = i
1727  end if
1728  end do
1729  deallocate (all_distances)
1730  end subroutine kdtree2_n_nearest_brute_force
1731 
1732  subroutine kdtree2_r_nearest_brute_force(tp, qv, r2, nfound, results)
1733  implicit none
1734  ! find the nearest neighbors to 'qv' with distance**2 <= r2 by exhaustive search.
1735  ! only use this subroutine for testing, as it is SLOW! The
1736  ! whole point of a k-d tree is to avoid doing what this subroutine
1737  ! does.
1738  type(kdtree2), pointer :: tp
1739  real(kind=realtype), intent(In) :: qv(:)
1740  real(kind=realtype), intent(In) :: r2
1741  integer(kind=intType), intent(out) :: nfound
1742  type(kdtree2_result) :: results(:)
1743 
1744  integer(kind=intType) :: i, nalloc
1745  real(kind=realtype), allocatable :: all_distances(:)
1746  ! ..
1747  allocate (all_distances(tp%n))
1748  do i = 1, tp%n
1749  all_distances(i) = square_distance(tp%dimen, qv, tp%the_data(:, i))
1750  end do
1751 
1752  nfound = 0
1753  nalloc = size(results, 1)
1754 
1755  do i = 1, tp%n
1756  if (all_distances(i) < r2) then
1757  ! insert it somewhere on the list
1758  if (nfound .lt. nalloc) then
1759  nfound = nfound + 1
1760  results(nfound)%dis = all_distances(i)
1761  results(nfound)%idx = i
1762  end if
1763  end if
1764  end do
1765  deallocate (all_distances)
1766 
1767  call kdtree2_sort_results(nfound, results)
1768 
1769  end subroutine kdtree2_r_nearest_brute_force
1770 
1771  subroutine kdtree2_sort_results(nfound, results)
1772  implicit none
1773  ! Use after search to sort results(1:nfound) in order of increasing
1774  ! distance.
1775  integer(kind=intType), intent(in) :: nfound
1776  type(kdtree2_result), target :: results(:)
1777  !
1778  !
1779 
1780  !THIS IS BUGGY WITH INTEL FORTRAN
1781  ! If (nfound .Gt. 1) Call heapsort(results(1:nfound)%dis,results(1:nfound)%ind,nfound)
1782  !
1783  if (nfound .gt. 1) call heapsort_struct(results, nfound)
1784 
1785  return
1786  end subroutine kdtree2_sort_results
1787 
1788  subroutine heapsort(a, ind, n)
1789  implicit none
1790  !
1791  ! Sort a(1:n) in ascending order, permuting ind(1:n) similarly.
1792  !
1793  ! If ind(k) = k upon input, then it will give a sort index upon output.
1794  !
1795  integer(kind=intType), intent(in) :: n
1796  real(kind=realtype), intent(inout) :: a(:)
1797  integer(kind=intType), intent(inout) :: ind(:)
1798 
1799  !
1800  !
1801  real(kind=realtype) :: value ! temporary for a value from a()
1802  integer(kind=intType) :: ivalue ! temporary for a value from ind()
1803 
1804  integer(kind=intType) :: i, j
1805  integer(kind=intType) :: ileft, iright
1806 
1807  ileft = n / 2 + 1
1808  iright = n
1809 
1810  ! do i=1,n
1811  ! ind(i)=i
1812  ! Generate initial idum array
1813  ! end do
1814 
1815  if (n .eq. 1) return
1816 
1817  do
1818  if (ileft > 1) then
1819  ileft = ileft - 1
1820  value = a(ileft); ivalue = ind(ileft)
1821  else
1822  value = a(iright); ivalue = ind(iright)
1823  a(iright) = a(1); ind(iright) = ind(1)
1824  iright = iright - 1
1825  if (iright == 1) then
1826  a(1) = value; ind(1) = ivalue
1827  return
1828  end if
1829  end if
1830  i = ileft
1831  j = 2 * ileft
1832  do while (j <= iright)
1833  if (j < iright) then
1834  if (a(j) < a(j + 1)) j = j + 1
1835  end if
1836  if (value < a(j)) then
1837  a(i) = a(j); ind(i) = ind(j)
1838  i = j
1839  j = j + j
1840  else
1841  j = iright + 1
1842  end if
1843  end do
1844  a(i) = value; ind(i) = ivalue
1845  end do
1846  end subroutine heapsort
1847 
1848  subroutine heapsort_struct(a, n)
1849  implicit none
1850  !
1851  ! Sort a(1:n) in ascending order
1852  !
1853  !
1854  integer(kind=intType), intent(in) :: n
1855  type(kdtree2_result), intent(inout) :: a(:)
1856 
1857  !
1858  !
1859  type(kdtree2_result) :: value ! temporary value
1860 
1861  integer(kind=intType) :: i, j
1862  integer(kind=intType) :: ileft, iright
1863 
1864  ileft = n / 2 + 1
1865  iright = n
1866 
1867  ! do i=1,n
1868  ! ind(i)=i
1869  ! Generate initial idum array
1870  ! end do
1871 
1872  if (n .eq. 1) return
1873 
1874  do
1875  if (ileft > 1) then
1876  ileft = ileft - 1
1877  value = a(ileft)
1878  else
1879  value = a(iright)
1880  a(iright) = a(1)
1881  iright = iright - 1
1882  if (iright == 1) then
1883  a(1) = value
1884  return
1885  end if
1886  end if
1887  i = ileft
1888  j = 2 * ileft
1889  do while (j <= iright)
1890  if (j < iright) then
1891  if (a(j)%dis < a(j + 1)%dis) j = j + 1
1892  end if
1893  if (value%dis < a(j)%dis) then
1894  a(i) = a(j);
1895  i = j
1896  j = j + j
1897  else
1898  j = iright + 1
1899  end if
1900  end do
1901  a(i) = value
1902  end do
1903  end subroutine heapsort_struct
1904 
1905 end module kdtree2_module
#define amin(a, b)
Definition: macros.h:30
#define amax(a, b)
Definition: macros.h:29
real(kind=realtype), parameter one
Definition: constants.F90:72
integer(kind=inttype), parameter bucket_size
Definition: kd_tree.f90:497
subroutine, public kdtree2_r_nearest_brute_force(tp, qv, r2, nfound, results)
Definition: kd_tree.f90:1733
subroutine, public kdtree2_sort_results(nfound, results)
Definition: kd_tree.f90:1772
subroutine, public kdtree2_n_nearest_brute_force(tp, qv, nn, results)
Definition: kd_tree.f90:1693
subroutine, public kdtree2_n_nearest_around_point(tp, idxin, correltime, nn, results)
Definition: kd_tree.f90:1066
integer(kind=inttype) function select_on_coordinate_value(v, ind, c, alpha, li, ui)
Definition: kd_tree.f90:832
integer(kind=inttype) function, public kdtree2_r_count(tp, qv, r2)
Definition: kd_tree.f90:1238
type(kdtree2) function, pointer, public kdtree2_create(input_data, dim, sort, rearrange)
Definition: kd_tree.f90:588
subroutine, public kdtree2_n_nearest(tp, qv, nn, results)
Definition: kd_tree.f90:1023
subroutine, public kdtree2destroy(tp)
Definition: kd_tree.f90:979
subroutine, public kdtree2_r_nearest(tp, qv, r2, nfound, nalloc, results)
Definition: kd_tree.f90:1110
subroutine, public kdtree2_r_nearest_around_point(tp, idxin, correltime, r2, nfound, nalloc, results)
Definition: kd_tree.f90:1171
integer(kind=inttype) function, public kdtree2_r_count_around_point(tp, idxin, correltime, r2)
Definition: kd_tree.f90:1284
subroutine, public pq_extract_max(a, e)
Definition: kd_tree.f90:248
subroutine, public pq_delete(a, i)
Definition: kd_tree.f90:436
real(kind=realtype) function, public pq_insert(a, dis, idx)
Definition: kd_tree.f90:278
subroutine, public pq_max(a, e)
Definition: kd_tree.f90:216
real(kind=realtype) function, public pq_maxpri(a)
Definition: kd_tree.f90:235
real(kind=realtype) function, public pq_replace_max(a, dis, idx)
Definition: kd_tree.f90:364
type(pq) function, public pq_create(results_in)
Definition: kd_tree.f90:77
integer, parameter realtype
Definition: precision.F90:112