SPEED
kdtree2_priority_queue_module Module Reference

Data Types

type  kdtree2_result
 
type  pq
 

Functions/Subroutines

type(pq) function, public pq_create (results_in)
 
subroutine, public pq_max (a, e)
 
real(kdkind) function, public pq_maxpri (a)
 
subroutine, public pq_extract_max (a, e)
 
real(kdkind) function, public pq_insert (a, dis, idx)
 
real(kdkind) function, public pq_replace_max (a, dis, idx)
 
subroutine, public pq_delete (a, i)
 

Function/Subroutine Documentation

◆ pq_create()

type(pq) function, public kdtree2_priority_queue_module::pq_create ( type(kdtree2_result), dimension(:), target  results_in)

Definition at line 100 of file kdtree2.f90.

101 !
102 ! Create a priority queue from ALREADY allocated
103 ! array pointers for storage. NOTE! It will NOT
104 ! add any alements to the heap, i.e. any existing
105 ! data in the input arrays will NOT be used and may
106 ! be overwritten.
107 !
108 ! usage:
109 ! real(kdkind), pointer :: x(:)
110 ! integer, pointer :: k(:)
111 ! allocate(x(1000),k(1000))
112 ! pq => pq_create(x,k)
113 !
114 type(kdtree2_result), target:: results_in(:)
115 type(pq) :: res
116 !
117 !
118 integer :: nalloc
119
120 nalloc = size(results_in,1)
121 if (nalloc .lt. 1) then
122 write (*,*) 'PQ_CREATE: error, input arrays must be allocated.'
123 end if
124 res%elems => results_in
125 res%heap_size = 0
126 return

Referenced by kdtree2_module::kdtree2_n_nearest(), and kdtree2_module::kdtree2_n_nearest_around_point().

Here is the caller graph for this function:

◆ pq_delete()

subroutine, public kdtree2_priority_queue_module::pq_delete ( type(pq), pointer  a,
integer  i 
)

Definition at line 455 of file kdtree2.f90.

456 !
457 ! delete item with index 'i'
458 !
459 type(pq),pointer :: a
460 integer :: i
461
462 if ((i .lt. 1) .or. (i .gt. a%heap_size)) then
463 write (*,*) 'PQ_DELETE: error, attempt to remove out of bounds element.'
464 stop
465 endif
466
467 ! swap the item to be deleted with the last element
468 ! and shorten heap by one.
469 a%elems(i) = a%elems(a%heap_size)
470 a%heap_size = a%heap_size - 1
471
472 call heapify(a,i)
473

◆ pq_extract_max()

subroutine, public kdtree2_priority_queue_module::pq_extract_max ( type(pq), pointer  a,
type(kdtree2_result), intent(out)  e 
)

Definition at line 269 of file kdtree2.f90.

270 !
271 ! return the priority and payload of maximum priority
272 ! element, and remove it from the queue.
273 ! (equivalent to 'pop()' on a stack)
274 !
275 type(pq),pointer :: a
276 type(kdtree2_result), intent(out) :: e
277
278 if (a%heap_size .ge. 1) then
279 !
280 ! return max as first element
281 !
282 e = a%elems(1)
283
284 !
285 ! move last element to first
286 !
287 a%elems(1) = a%elems(a%heap_size)
288 a%heap_size = a%heap_size-1
289 call heapify(a,1)
290 return
291 else
292 write (*,*) 'PQ_EXTRACT_MAX: error, attempted to pop non-positive PQ'
293 stop
294 end if
295

Referenced by pq_replace_max().

Here is the caller graph for this function:

◆ pq_insert()

real(kdkind) function, public kdtree2_priority_queue_module::pq_insert ( type(pq), pointer  a,
real(kdkind), intent(in)  dis,
integer, intent(in)  idx 
)

Definition at line 299 of file kdtree2.f90.

300 !
301 ! Insert a new element and return the new maximum priority,
302 ! which may or may not be the same as the old maximum priority.
303 !
304 type(pq),pointer :: a
305 real(kdkind), intent(in) :: dis
306 integer, intent(in) :: idx
307 ! type(kdtree2_result), intent(in) :: e
308 !
309 integer :: i, isparent
310 real(kdkind) :: parentdis
311 !
312
313 ! if (a%heap_size .ge. a%max_elems) then
314 ! write (*,*) 'PQ_INSERT: error, attempt made to insert element on full PQ'
315 ! stop
316 ! else
317 a%heap_size = a%heap_size + 1
318 i = a%heap_size
319
320 do while (i .gt. 1)
321 isparent = int(i/2)
322 parentdis = a%elems(isparent)%dis
323 if (dis .gt. parentdis) then
324 ! move what was in i's parent into i.
325 a%elems(i)%dis = parentdis
326 a%elems(i)%idx = a%elems(isparent)%idx
327 i = isparent
328 else
329 exit
330 endif
331 end do
332
333 ! insert the element at the determined position
334 a%elems(i)%dis = dis
335 a%elems(i)%idx = idx
336
337 pq_insert = a%elems(1)%dis
338 return
339 ! end if
340

References pq_insert().

Referenced by pq_insert(), and pq_replace_max().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pq_max()

subroutine, public kdtree2_priority_queue_module::pq_max ( type(pq), pointer  a,
type(kdtree2_result), intent(out)  e 
)

Definition at line 239 of file kdtree2.f90.

240 !
241 ! return the priority and its payload of the maximum priority element
242 ! on the queue, which should be the first one, if it is
243 ! in heapified form.
244 !
245 type(pq),pointer :: a
246 type(kdtree2_result),intent(out) :: e
247
248 if (a%heap_size .gt. 0) then
249 e = a%elems(1)
250 else
251 write (*,*) 'PQ_MAX: ERROR, heap_size < 1'
252 stop
253 endif
254 return

◆ pq_maxpri()

real(kdkind) function, public kdtree2_priority_queue_module::pq_maxpri ( type(pq), pointer  a)

Definition at line 257 of file kdtree2.f90.

258 type(pq), pointer :: a
259
260 if (a%heap_size .gt. 0) then
261 pq_maxpri = a%elems(1)%dis
262 else
263 write (*,*) 'PQ_MAX_PRI: ERROR, heapsize < 1'
264 stop
265 endif
266 return

References pq_maxpri().

Referenced by pq_maxpri().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pq_replace_max()

real(kdkind) function, public kdtree2_priority_queue_module::pq_replace_max ( type(pq), pointer  a,
real(kdkind), intent(in)  dis,
integer, intent(in)  idx 
)

Definition at line 384 of file kdtree2.f90.

385 !
386 ! Replace the extant maximum priority element
387 ! in the PQ with (dis,idx). Return
388 ! the new maximum priority, which may be larger
389 ! or smaller than the old one.
390 !
391 type(pq),pointer :: a
392 real(kdkind), intent(in) :: dis
393 integer, intent(in) :: idx
394! type(kdtree2_result), intent(in) :: e
395 ! not tested as well!
396
397 integer :: parent, child, N
398 real(kdkind) :: prichild, prichildp1
399
400 type(kdtree2_result) :: etmp
401
402 if (.true.) then
403 n=a%heap_size
404 if (n .ge. 1) then
405 parent =1
406 child=2
407
408 loop: do while (child .le. n)
409 prichild = a%elems(child)%dis
410
411 !
412 ! posibly child+1 has higher priority, and if
413 ! so, get it, and increment child.
414 !
415
416 if (child .lt. n) then
417 prichildp1 = a%elems(child+1)%dis
418 if (prichild .lt. prichildp1) then
419 child = child+1
420 prichild = prichildp1
421 endif
422 endif
423
424 if (dis .ge. prichild) then
425 exit loop
426 ! we have a proper place for our new element,
427 ! bigger than either children's priority.
428 else
429 ! move child into parent.
430 a%elems(parent) = a%elems(child)
431 parent = child
432 child = 2*parent
433 end if
434 end do loop
435 a%elems(parent)%dis = dis
436 a%elems(parent)%idx = idx
437 pq_replace_max = a%elems(1)%dis
438 else
439 a%elems(1)%dis = dis
440 a%elems(1)%idx = idx
441 pq_replace_max = dis
442 endif
443 else
444 !
445 ! slower version using elementary pop and push operations.
446 !
447 call pq_extract_max(a,etmp)
448 etmp%dis = dis
449 etmp%idx = idx
450 pq_replace_max = pq_insert(a,dis,idx)
451 endif
452 return

References pq_extract_max(), pq_insert(), and pq_replace_max().

Referenced by pq_replace_max().

Here is the call graph for this function:
Here is the caller graph for this function: