M_orderpack__mulcnt.f90 Source File


Contents


Source Code

Module M_orderpack__mulcnt
use,intrinsic :: iso_fortran_env, only : int8, int16, int32, int64, real32, real64, real128
Use M_orderpack__uniinv
implicit none
Private
integer,parameter :: f_char=selected_char_kind("DEFAULT")
public :: mulcnt
!>
!!##NAME
!!    occurrences(3f) - [M_orderpack:MULTIPLICITY] Give the multiplicity for each
!!                 array value (number of times that it appears in the array)
!!
!!##SYNOPSIS
!!
!!     Subroutine Occurrences (INVALS, IMULT)
!!
!!       ${TYPE} (kind=${KIND}), Intent (In) :: INVALS(:)
!!       Integer, Intent (Out)               :: IMULT(:)
!!
!!    Where ${TYPE}(kind=${KIND}) may be
!!
!!       o Real(kind=real32)
!!       o Real(kind=real64)
!!       o Integer(kind=int32)
!!       o Character(kind=selected_char_kind("DEFAULT"),len=*)
!!
!!##DESCRIPTION
!!     OCCURRENCES(3f) Gives, for each array element, its multiplicity
!!     (number of times that it appears in the array).
!!
!!     Internally, the number of times that a value appears in the array is
!!     computed by using inverse ranking, counting for each rank the number
!!     of values that "collide" to this rank, and returning this sum to
!!     the locations in the original set. It uses subroutine RANK_ORDERS(3f).
!!
!!##OPTIONS
!!     INVALS      input array
!!     IMULT      array containing how often the value in INVALS
!!                appears in INVALS
!!
!!##EXAMPLES
!!
!! Sample program:
!!
!!      program demo_occurrences
!!      use M_orderpack, only : occurrences
!!      ! determine how many times each value appears in an input array
!!      implicit none
!!      character(len=*),parameter    :: g='(*(g0,1x))'
!!      character(len=20),allocatable :: strings(:)
!!      integer,allocatable           :: cindx(:)
!!      integer                       :: csz
!!      integer                       :: i
!!         ! each name appears the number of times its name represents
!!         strings= [ character(len=20) ::                           &
!!         & 'two  ',  'four ', 'three', 'five',   'five',           &
!!         & 'two  ',  'four ', 'three', 'five',   'five',           &
!!         & 'four ',  'four ', 'three', 'one  ',  'five']
!!         csz=size(strings)
!!         if(allocated(cindx))deallocate(cindx)
!!         allocate(cindx(csz))
!!         call occurrences(strings,cindx)
!!         write(*,g)(trim(strings(i)),i=1,csz)
!!         write(*,g)cindx
!!      end program demo_occurrences
!!
!! Results:
!!
!!  two four three five five two four three five five four four three one five
!!  2   4    3     5    5    2   4    3     5    5    4    4    3     1   5
!!
!!##AUTHOR
!!    Michel Olagnon, Mar 2000
!!##MAINTAINER
!!    John Urban, 2022.04.16
!!##LICENSE
!!    CC0-1.0
interface mulcnt
  module procedure real64_mulcnt, real32_mulcnt, int32_mulcnt, f_char_mulcnt
end interface mulcnt
contains
Subroutine real64_mulcnt (INVALS, IMULT)
! __________________________________________________________
      Real (kind=real64), Dimension (:), Intent (In) :: INVALS
      Integer, Dimension (:), Intent (Out) :: IMULT
! __________________________________________________________
      Integer, Dimension (Size(INVALS)) :: IWRKT
      Integer, Dimension (Size(INVALS)) :: ICNTT
      Integer :: ICRS
! __________________________________________________________
      Call UNIINV (INVALS, IWRKT)
      ICNTT = 0
      Do ICRS = 1, Size(INVALS)
            ICNTT(IWRKT(ICRS)) = ICNTT(IWRKT(ICRS)) + 1
      End Do
      Do ICRS = 1, Size(INVALS)
            IMULT(ICRS) = ICNTT(IWRKT(ICRS))
      End Do
!
End Subroutine real64_mulcnt
Subroutine real32_mulcnt (INVALS, IMULT)
! __________________________________________________________
      Real (kind=real32), Dimension (:), Intent (In) :: INVALS
      Integer, Dimension (:), Intent (Out) :: IMULT
! __________________________________________________________
      Integer, Dimension (Size(INVALS)) :: IWRKT
      Integer, Dimension (Size(INVALS)) :: ICNTT
      Integer :: ICRS
! __________________________________________________________
      Call UNIINV (INVALS, IWRKT)
      ICNTT = 0
      Do ICRS = 1, Size(INVALS)
            ICNTT(IWRKT(ICRS)) = ICNTT(IWRKT(ICRS)) + 1
      End Do
      Do ICRS = 1, Size(INVALS)
            IMULT(ICRS) = ICNTT(IWRKT(ICRS))
      End Do
!
End Subroutine real32_mulcnt
Subroutine int32_mulcnt (INVALS, IMULT)
! __________________________________________________________
      Integer (kind=int32), Dimension (:), Intent (In) :: INVALS
      Integer, Dimension (:), Intent (Out) :: IMULT
! __________________________________________________________
      Integer, Dimension (Size(INVALS)) :: IWRKT
      Integer, Dimension (Size(INVALS)) :: ICNTT
      Integer :: ICRS
! __________________________________________________________
      Call UNIINV (INVALS, IWRKT)
      ICNTT = 0
      Do ICRS = 1, Size(INVALS)
            ICNTT(IWRKT(ICRS)) = ICNTT(IWRKT(ICRS)) + 1
      End Do
      Do ICRS = 1, Size(INVALS)
            IMULT(ICRS) = ICNTT(IWRKT(ICRS))
      End Do
!
End Subroutine int32_mulcnt
Subroutine f_char_mulcnt (INVALS, IMULT)
! __________________________________________________________
      character (kind=f_char,len=*), Dimension (:), Intent (In) :: INVALS
      Integer, Dimension (:), Intent (Out) :: IMULT
! __________________________________________________________
      Integer, Dimension (Size(INVALS)) :: IWRKT
      Integer, Dimension (Size(INVALS)) :: ICNTT
      Integer :: ICRS
! __________________________________________________________
      Call UNIINV (INVALS, IWRKT)
      ICNTT = 0
      Do ICRS = 1, Size(INVALS)
            ICNTT(IWRKT(ICRS)) = ICNTT(IWRKT(ICRS)) + 1
      End Do
      Do ICRS = 1, Size(INVALS)
            IMULT(ICRS) = ICNTT(IWRKT(ICRS))
      End Do
!
End Subroutine f_char_mulcnt
end module M_orderpack__mulcnt