47 real(kind_real) :: lower,upper
55 real(kind_real) :: cut_val
57 real(kind_real) :: cut_val_left, cut_val_right
70 real(kind_real),
pointer :: the_data(:,:) => null()
84 integer,
pointer :: ind(:) => null()
88 logical :: sort = .false.
90 logical :: rearrange = .true.
91 real(kind_real),
pointer :: rearranged_data(:,:) => null()
110 integer :: nn, nfound
111 real(kind_real) :: ballsize
112 integer :: centeridx=999, correltime=9999
118 real(kind_real),
pointer :: qv(:)
121 real(kind_real),
pointer :: data(:,:)
122 integer,
pointer :: ind(:)
150 logical,
intent(in),
optional :: sort
151 logical,
intent(in),
optional :: rearrange
154 real(kind_real),
target :: input_data(:,:)
159 mr%the_data => input_data
162 mr%n =
size(input_data,2)
166 if (
present(sort))
then 172 if (
present(rearrange))
then 173 mr%rearrange = rearrange
175 mr%rearrange = .true.
178 allocate(mr%rearranged_data(3,mr%n))
179 if (mr%rearrange)
then 181 mr%rearranged_data(:,i) = mr%the_data(:,mr%ind(i))
184 mr%rearranged_data = mr%the_data
195 type(tree_node),
pointer :: dummy => null()
197 allocate (tp%ind(tp%n))
216 integer,
intent (In) :: l, u
221 real(kind_real) :: average
260 if (
associated(parent))
then 261 if (i .ne. parent%cut_dim)
then 268 res%box(i) = parent%box(i)
273 c = maxloc(res%box%upper-res%box%lower,1)
290 average = sum(tp%the_data(c,tp%ind(l:u))) /
real(u-l+1,
kind_real)
292 average = (res%box(c)%upper + res%box(c)%lower)/2.0
295 res%cut_val = average
308 if (
associated(res%right) .eqv. .false.)
then 309 res%box = res%left%box
310 res%cut_val_left = res%left%box(c)%upper
311 res%cut_val = res%cut_val_left
312 elseif (
associated(res%left) .eqv. .false.)
then 313 res%box = res%right%box
314 res%cut_val_right = res%right%box(c)%lower
315 res%cut_val = res%cut_val_right
317 res%cut_val_right = res%right%box(c)%lower
318 res%cut_val_left = res%left%box(c)%upper
319 res%cut_val = (res%cut_val_left + res%cut_val_right)/2
326 res%box%upper =
max(res%left%box%upper,res%right%box%upper)
327 res%box%lower =
min(res%left%box%lower,res%right%box%lower)
349 integer,
intent (In) :: c, li, ui
350 real(kind_real),
intent(in) :: alpha
352 real(kind_real) :: v(1:,1:)
372 if (
infeq(v(c,ind(lb)),alpha) )
then 377 tmp = ind(lb); ind(lb) = ind(rb); ind(rb) = tmp
383 if (
infeq(v(c,ind(lb)),alpha))
then 396 integer,
intent (In) :: c, k, li, ui
398 integer :: i, l, m, s, t, u
400 real(kind_real) :: v(:,:)
409 if (
inf(v(c,ind(i)),v(c,t)))
then 430 type(interval),
intent(out) :: interv
433 integer,
intent (In) :: c, l, u
436 real(kind_real) :: last, lmax, lmin, t, smin,smax
440 real(kind_real),
pointer :: v(:,:)
441 integer,
pointer :: ind(:)
443 v => tp%the_data(1:,1:)
450 do i = l + 2, ulocal, 2
453 if (
sup(lmin,lmax))
then 458 if (
sup(smin,lmin)) smin = lmin
459 if (
inf(smax,lmax)) smax = lmax
461 if (i==ulocal+1)
then 462 last = v(c,ind(ulocal))
463 if (
sup(smin,last)) smin = last
464 if (
inf(smax,last)) smax = last
484 deallocate(tp%rearranged_data)
485 nullify(tp%rearranged_data)
501 if (
associated(np%left))
then 505 if (
associated(np%right))
then 509 if (
associated(np%box))
deallocate(np%box)
524 real(kind_real),
target,
intent (In) :: qv(:)
525 integer,
intent (In) :: nn
529 sr%ballsize = huge(1.0)
535 sr%overflow = .false.
537 sr%results => results
542 sr%rearrange = tp%rearrange
543 sr%Data => tp%rearranged_data
562 real(kind_real),
target,
intent (In) :: qv(:)
563 real(kind_real),
intent(in) :: r2
582 sr%rearrange = tp%rearrange
583 sr%Data => tp%rearranged_data
589 sr%overflow = .false.
602 integer,
intent(in) :: n
604 if (
size(
sr%results,1) .lt. n)
then 605 write (*,*)
'KD_TREE_TRANS: you did not provide enough storage for results(1:n)' 619 real(kind_real) :: res
622 real(kind_real),
intent(in) :: iv(3),qv(3)
626 res = sum( (iv-qv)**2 )
635 real(kind_real) :: res, ilat, ilon, ir, qlat, qlon, qr
638 real(kind_real),
intent(in) :: iv(3),qv(3)
642 call scoord(iv(1),iv(2),iv(3),ilat,ilon,ir)
643 call scoord(qv(1),qv(2),qv(3),qlat,qlon,qr)
650 recursive subroutine search(node)
661 type(
tree_node),
pointer :: ncloser, nfarther
663 integer :: cut_dim, i
665 real(kind_real) :: qval, dis
666 real(kind_real) :: ballsize
667 real(kind_real),
pointer :: qv(:)
670 if ((
associated(node%left) .and.
associated(node%right)) .eqv. .false.)
then 672 if (
sr%nn .eq. 0)
then 680 cut_dim = node%cut_dim
683 if (
inf(qval,node%cut_val))
then 685 nfarther => node%right
686 dis = (node%cut_val_right - qval)**2
689 ncloser => node%right
690 nfarther => node%left
691 dis = (node%cut_val_left - qval)**2
695 if (
associated(ncloser))
call search(ncloser)
698 if (
associated(nfarther))
then 699 ballsize =
sr%ballsize
701 if (
infeq(dis,ballsize))
then 710 if (i .ne. cut_dim)
then 712 if (
sup(dis,ballsize))
then 727 real(kind_real) function dis2_from_bnd(x,amin,amax)
result (res)
731 real(kind_real),
intent(in) :: x, amin,amax
733 if (
sup(x,amax))
then 737 if (
inf(x,amin))
then 754 real(kind_real),
pointer :: qv(:)
755 integer,
pointer :: ind(:)
756 real(kind_real),
pointer :: data(:,:)
758 integer :: i, indexofi, centeridx, correltime
759 real(kind_real) :: ballsize, sd, ssd, newpri
761 type(pq),
pointer :: pqp
771 ballsize =
sr%ballsize
772 rearrange =
sr%rearrange
774 data =>
sr%Data(1:,1:)
775 centeridx =
sr%centeridx
776 correltime =
sr%correltime
782 mainloop:
do i = node%l, node%u
792 if (
sup(sd,ballsize)) cycle mainloop
794 if (centeridx > 0)
then 795 if (abs(indexofi-centeridx) < correltime) cycle mainloop
817 if (
sr%nfound .lt.
sr%nn)
then 821 sr%nfound =
sr%nfound +1
823 if (
sr%nfound .eq.
sr%nn) ballsize = newpri
842 sr%ballsize = ballsize
852 real(kind_real),
pointer :: qv(:)
853 integer,
pointer :: ind(:)
854 real(kind_real),
pointer :: data(:,:)
857 integer :: i, indexofi
858 integer :: centeridx, correltime, nn
859 real(kind_real) :: ballsize, sd, ssd
866 ballsize =
sr%ballsize
867 rearrange =
sr%rearrange
869 data =>
sr%Data(1:,1:)
870 centeridx =
sr%centeridx
871 correltime =
sr%correltime
876 mainloop:
do i = node%l, node%u
907 if (
sup(sd,ballsize)) cycle mainloop
909 if (centeridx > 0)
then 910 if (abs(indexofi-centeridx)<correltime) cycle mainloop
914 if (nfound .gt.
sr%nalloc)
then 919 sr%results(nfound)%dis = sd
920 sr%results(nfound)%sdis = ssd
921 sr%results(nfound)%idx = indexofi
933 integer,
intent(in) :: nfound
934 type(kdtree2_result),
target :: results(:)
950 integer,
intent(in) :: n
951 type(kdtree2_result),
intent(inout) :: a(:)
955 type(kdtree2_result) ::
value 958 integer :: ileft,iright
978 if (iright == 1)
then 985 do while (j <= iright)
987 if(
inf(a(j)%dis,a(j+1)%dis)) j=j+1
989 if(
inf(
value%dis,a(j)%dis))
then
integer, parameter, public kind_real