calc_median Subroutine

public subroutine calc_median(tab, mask, md)

Function to calculate the median value of a series.

  • Input array containing the values for which the median is to be calculated
  • Optional mask to include/exclude certain values from the array
  • Output: the calculated median value

Arguments

Type IntentOptional Attributes Name
real(kind=R8), intent(in), dimension(:) :: tab

series 1D array

logical(kind=I4), intent(in), optional, dimension(:) :: mask

mask

real(kind=R8), intent(out) :: md

result: series median value


Calls

proc~~calc_median~~CallsGraph proc~calc_median calc_median sort_array2 sort_array2 proc~calc_median->sort_array2

Called by

proc~~calc_median~~CalledByGraph proc~calc_median calc_median proc~count_cell count_cell proc~count_cell->proc~calc_median proc~median_filter median_filter proc~median_filter->proc~calc_median proc~median_smooth median_smooth proc~median_filter->proc~median_smooth proc~median_smooth->proc~calc_median program~test_stat test_stat program~test_stat->proc~calc_median proc~topology topology proc~topology->proc~count_cell program~test_morpho test_morpho program~test_morpho->proc~count_cell program~test_smooth test_smooth program~test_smooth->proc~median_filter program~test_smooth->proc~median_smooth

Source Code

   subroutine calc_median(tab, mask, md)
   !================================================================================================
   !! Function to calculate the median value of a series.
   !!
   !! + Input array containing the values for which the median is to be calculated
   !! + Optional mask to include/exclude certain values from the array
   !! + Output: the calculated median value
   !------------------------------------------------------------------------------------------------
   implicit none
   real   (kind=R8), intent(in ), dimension(:)            :: tab  !! *series 1D array*
   logical(kind=I4), intent(in ), dimension(:), optional  :: mask !! *mask*
   real   (kind=R8), intent(out)                          :: md   !! *result: series median value*

      integer(kind=I4) :: lg, nz ! lg: size of the tab array; nz: number of elements to consider
      integer(kind=I4) :: i, ii  ! i: loop counter; ii: counter for tab_tmp

      real(kind=R8), allocatable, dimension(:) :: tab_tmp ! Temporary array to store filtered values

      md = 0._R8                    ! Initialize the median value to 0

      lg = size( tab )              ! Get the size of the input array
      nz = lg                       ! Initialize the number of elements to lg

      if ( present(mask) ) then     ! Check if a mask is provided

         nz = count( mask )         ! Count the number of true elements in the mask
         allocate( tab_tmp(1:nz) )  ! Allocate memory for the temporary array based on the number of elements to consider

         ii = 0                     ! Initialize the counter for tab_tmp
         do i = 1, lg               ! Loop through each element of the input array
            if ( mask(i) ) then     ! If the element is included in the mask
               ii = ii + 1          ! Increment the counter
               tab_tmp(ii) = tab(i) ! Copy the corresponding value into the temporary array
            endif
         enddo
         if (ii /= nz) stop 'error calc_median' ! Check if the number of copied elements matches nz; if not, stop the program

      else ! If no mask is provided

         tab_tmp = tab ! Copy the input array into tab_tmp

      endif

      if (nz == 1) then             ! If only one element is present
         md = tab_tmp(1)            ! The median is the single element
         return                     ! Exit the subroutine
      endif
      if (nz == 2) then                            ! If two elements are present
         md = 0.5_R8*(tab_tmp(1) + tab_tmp(2))     ! The median is the average of the two elements
         return                                    ! Exit the subroutine
      endif

      call sort_array2(tab_inout = tab_tmp(1:nz), n = nz)         ! Call a subroutine to sort the temporary array

      if ( mod(nz, 2) == 0 ) then                                 ! Check if the number of elements is even
         md = 0.5_R8 * ( tab_tmp( nz/2 ) + tab_tmp( nz/2 + 1) )   ! The median is the average of the two middle elements
      else                                                        ! If the number of elements is odd
         md = tab_tmp( (nz-1)/2 )                                 ! The median is the middle element
      endif

      deallocate( tab_tmp )                                       ! Free the allocated memory for tab_tmp

   return                                                         ! Exit the subroutine
   endsubroutine calc_median