Unique

Here is a simple Fortran subroutine to return only the unique values in a vector (inspired by Matlab’s unique function). Note, this implementation is for integer arrays, but could easily be modified for any type. This code is not particularly optimized, so there may be a more efficient way to do it. It does demonstrate Fortran array transformational functions such as pack and count. Note that to duplicate the Matlab function, the output array must also be sorted.

 subroutine unique(vec,vec_unique)
 ! Return only the unique values from vec.

 implicit none

 integer,dimension(:),intent(in) :: vec
 integer,dimension(:),allocatable,intent(out) :: vec_unique

 integer :: i,num
 logical,dimension(size(vec)) :: mask

 mask = .false.

 do i=1,size(vec)

     !count the number of occurrences of this element:
     num = count( vec(i)==vec )

     if (num==1) then
         !there is only one, flag it:
         mask(i) = .true.
     else
         !flag this value only if it hasn't already been flagged:
         if (.not. any(vec(i)==vec .and. mask) ) mask(i) = .true.
     end if

 end do

 !return only flagged elements:
 allocate( vec_unique(count(mask)) )
 vec_unique = pack( vec, mask )

 !if you also need it sorted, then do so.
 ! For example, with slatec routine:
 !call ISORT (vec_unique, [0], size(vec_unique), 1)

 end subroutine unique
Tagged with: ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*