index_list_from_segment_list Subroutine

private pure subroutine index_list_from_segment_list(index_list, seg_list)

Extracts a sorted list of unique indices from a list of segments.

This subroutine takes a list of segments and generates a sorted list of unique indices from the min and max values of each segment, including values just before and after the min and max.

Arguments

Type IntentOptional Attributes Name
integer(kind=int32), intent(out), allocatable :: index_list(:)
type(segment_t), intent(in) :: seg_list(:)

Source Code

   pure subroutine index_list_from_segment_list(index_list, seg_list)
      use, intrinsic :: iso_fortran_env, only: int32
      use :: forgex_sort_m, only: insertion_sort
      implicit none
      type(segment_t), intent(in) :: seg_list(:)
      integer(int32), intent(out), allocatable :: index_list(:)
      integer(int32), allocatable :: cache(:)

      integer :: siz, i, k

      siz = size(seg_list, dim=1)   ! Get the size of the list.

      allocate(index_list(6*siz))   ! Allocate an `index_list` of the required size
      allocate(cache(6*siz))        ! Allocate an array for cache.

      do i = 1, siz
         ! Add the `min` and `max` values of each segment, as well as the values
         ! before and after them, to the index list.
         index_list(6*i-5) = seg_list(i)%min - 1
         index_list(6*i-4) = seg_list(i)%min
         index_list(6*i-3) = seg_list(i)%min + 1
         index_list(6*i-2) = seg_list(i)%max - 1
         index_list(6*i-1) = seg_list(i)%max
         index_list(6*i)   = seg_list(i)%max + 1
      end do

      call insertion_sort(index_list)  ! Sort the `index_list` in ascending order.

      ! Initialize
      cache(1) = index_list(1)
      k = 1
      ! Scan the entire `index_list`.
      do i = 2, siz*6
         if (index_list(i-1) /= index_list(i)) then
            ! Add only unique values to the `cache`.
            ! At the same time, count unique values.
            k = k + 1
            cache(k) = index_list(i)
         end if
      end do


      deallocate(index_list)     ! Deallocate the old `index_list`.
      allocate(index_list(k))    ! Allocate a new `index_list` based on the number of unique indices.
      index_list(:) = cache(1:k) ! Copy the data of `cahce(1:k)` into the `index_list(:)`.
   end subroutine index_list_from_segment_list