2014-04-01 18:37:27 +02:00
|
|
|
BEGIN_TEMPLATE
|
|
|
|
subroutine insertion_$Xsort (x,iorder,isize)
|
|
|
|
implicit none
|
2014-04-07 20:01:30 +02:00
|
|
|
BEGIN_DOC
|
|
|
|
! Sort array x(isize) using the insertion sort algorithm.
|
|
|
|
! iorder in input should be (1,2,3,...,isize), and in output
|
|
|
|
! contains the new order of the elements.
|
|
|
|
END_DOC
|
2016-02-19 00:20:28 +01:00
|
|
|
integer,intent(in) :: isize
|
2014-04-07 20:01:30 +02:00
|
|
|
$type,intent(inout) :: x(isize)
|
|
|
|
integer,intent(inout) :: iorder(isize)
|
|
|
|
$type :: xtmp
|
|
|
|
integer :: i, i0, j, jmax
|
|
|
|
|
2017-04-19 15:31:12 +02:00
|
|
|
do i=2,isize
|
2014-04-07 20:01:30 +02:00
|
|
|
xtmp = x(i)
|
|
|
|
i0 = iorder(i)
|
2017-04-19 15:31:12 +02:00
|
|
|
do j = i-1,1,-1
|
|
|
|
if ((x(j) <= xtmp)) exit
|
|
|
|
x(j+1) = x(j)
|
|
|
|
iorder(j+1) = iorder(j)
|
2014-04-07 20:01:30 +02:00
|
|
|
enddo
|
|
|
|
x(j+1) = xtmp
|
|
|
|
iorder(j+1) = i0
|
2014-04-01 18:37:27 +02:00
|
|
|
enddo
|
|
|
|
end subroutine insertion_$Xsort
|
|
|
|
|
2017-04-19 15:31:12 +02:00
|
|
|
|
2014-04-01 18:37:27 +02:00
|
|
|
subroutine heap_$Xsort(x,iorder,isize)
|
|
|
|
implicit none
|
2014-04-07 20:01:30 +02:00
|
|
|
BEGIN_DOC
|
|
|
|
! Sort array x(isize) using the heap sort algorithm.
|
|
|
|
! iorder in input should be (1,2,3,...,isize), and in output
|
|
|
|
! contains the new order of the elements.
|
|
|
|
END_DOC
|
2016-02-19 00:20:28 +01:00
|
|
|
integer,intent(in) :: isize
|
2014-04-07 20:01:30 +02:00
|
|
|
$type,intent(inout) :: x(isize)
|
|
|
|
integer,intent(inout) :: iorder(isize)
|
2014-04-01 18:37:27 +02:00
|
|
|
|
2014-04-07 20:01:30 +02:00
|
|
|
integer :: i, k, j, l, i0
|
|
|
|
$type :: xtemp
|
|
|
|
|
|
|
|
l = isize/2+1
|
|
|
|
k = isize
|
|
|
|
do while (.True.)
|
2014-04-01 18:37:27 +02:00
|
|
|
if (l>1) then
|
|
|
|
l=l-1
|
|
|
|
xtemp = x(l)
|
|
|
|
i0 = iorder(l)
|
|
|
|
else
|
|
|
|
xtemp = x(k)
|
|
|
|
i0 = iorder(k)
|
|
|
|
x(k) = x(1)
|
|
|
|
iorder(k) = iorder(1)
|
|
|
|
k = k-1
|
|
|
|
if (k == 1) then
|
2014-04-07 20:01:30 +02:00
|
|
|
x(1) = xtemp
|
2014-04-01 18:37:27 +02:00
|
|
|
iorder(1) = i0
|
|
|
|
exit
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
i=l
|
|
|
|
j = ishft(l,1)
|
|
|
|
do while (j<k)
|
2014-04-07 20:01:30 +02:00
|
|
|
if ( x(j) < x(j+1) ) then
|
|
|
|
j=j+1
|
|
|
|
endif
|
|
|
|
if (xtemp < x(j)) then
|
|
|
|
x(i) = x(j)
|
|
|
|
iorder(i) = iorder(j)
|
|
|
|
i = j
|
|
|
|
j = ishft(j,1)
|
|
|
|
else
|
|
|
|
j = k+1
|
|
|
|
endif
|
2014-04-01 18:37:27 +02:00
|
|
|
enddo
|
|
|
|
if (j==k) then
|
2014-04-07 20:01:30 +02:00
|
|
|
if (xtemp < x(j)) then
|
|
|
|
x(i) = x(j)
|
|
|
|
iorder(i) = iorder(j)
|
|
|
|
i = j
|
|
|
|
j = ishft(j,1)
|
|
|
|
else
|
|
|
|
j = k+1
|
|
|
|
endif
|
2014-04-01 18:37:27 +02:00
|
|
|
endif
|
2014-04-07 20:01:30 +02:00
|
|
|
x(i) = xtemp
|
2014-04-01 18:37:27 +02:00
|
|
|
iorder(i) = i0
|
2014-04-07 20:01:30 +02:00
|
|
|
enddo
|
2014-04-01 18:37:27 +02:00
|
|
|
end subroutine heap_$Xsort
|
|
|
|
|
|
|
|
subroutine heap_$Xsort_big(x,iorder,isize)
|
|
|
|
implicit none
|
2014-04-07 20:01:30 +02:00
|
|
|
BEGIN_DOC
|
|
|
|
! Sort array x(isize) using the heap sort algorithm.
|
|
|
|
! iorder in input should be (1,2,3,...,isize), and in output
|
|
|
|
! contains the new order of the elements.
|
|
|
|
! This is a version for very large arrays where the indices need
|
|
|
|
! to be in integer*8 format
|
|
|
|
END_DOC
|
2016-02-19 00:20:28 +01:00
|
|
|
integer*8,intent(in) :: isize
|
2014-04-07 20:01:30 +02:00
|
|
|
$type,intent(inout) :: x(isize)
|
|
|
|
integer*8,intent(inout) :: iorder(isize)
|
2014-04-01 18:37:27 +02:00
|
|
|
|
2014-04-07 20:01:30 +02:00
|
|
|
integer*8 :: i, k, j, l, i0
|
|
|
|
$type :: xtemp
|
|
|
|
|
|
|
|
l = isize/2+1
|
|
|
|
k = isize
|
|
|
|
do while (.True.)
|
2014-04-01 18:37:27 +02:00
|
|
|
if (l>1) then
|
|
|
|
l=l-1
|
|
|
|
xtemp = x(l)
|
|
|
|
i0 = iorder(l)
|
|
|
|
else
|
|
|
|
xtemp = x(k)
|
|
|
|
i0 = iorder(k)
|
|
|
|
x(k) = x(1)
|
|
|
|
iorder(k) = iorder(1)
|
|
|
|
k = k-1
|
|
|
|
if (k == 1) then
|
2014-04-07 20:01:30 +02:00
|
|
|
x(1) = xtemp
|
2014-04-01 18:37:27 +02:00
|
|
|
iorder(1) = i0
|
|
|
|
exit
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
i=l
|
|
|
|
j = ishft(l,1)
|
|
|
|
do while (j<k)
|
2014-04-07 20:01:30 +02:00
|
|
|
if ( x(j) < x(j+1) ) then
|
|
|
|
j=j+1
|
|
|
|
endif
|
|
|
|
if (xtemp < x(j)) then
|
|
|
|
x(i) = x(j)
|
|
|
|
iorder(i) = iorder(j)
|
|
|
|
i = j
|
|
|
|
j = ishft(j,1)
|
|
|
|
else
|
|
|
|
j = k+1
|
|
|
|
endif
|
2014-04-01 18:37:27 +02:00
|
|
|
enddo
|
|
|
|
if (j==k) then
|
2014-04-07 20:01:30 +02:00
|
|
|
if (xtemp < x(j)) then
|
|
|
|
x(i) = x(j)
|
|
|
|
iorder(i) = iorder(j)
|
|
|
|
i = j
|
|
|
|
j = ishft(j,1)
|
|
|
|
else
|
|
|
|
j = k+1
|
|
|
|
endif
|
2014-04-01 18:37:27 +02:00
|
|
|
endif
|
2014-04-07 20:01:30 +02:00
|
|
|
x(i) = xtemp
|
2014-04-01 18:37:27 +02:00
|
|
|
iorder(i) = i0
|
2014-04-07 20:01:30 +02:00
|
|
|
enddo
|
|
|
|
|
2017-01-31 21:48:47 +01:00
|
|
|
end subroutine heap_$Xsort_big
|
2014-04-01 18:37:27 +02:00
|
|
|
|
2017-04-14 15:04:29 +02:00
|
|
|
subroutine sorted_$Xnumber(x,isize,n)
|
|
|
|
implicit none
|
|
|
|
BEGIN_DOC
|
|
|
|
! Returns the number of sorted elements
|
|
|
|
END_DOC
|
|
|
|
integer, intent(in) :: isize
|
2017-04-14 18:11:02 +02:00
|
|
|
$type, intent(in) :: x(isize)
|
2017-04-14 15:04:29 +02:00
|
|
|
integer, intent(out) :: n
|
|
|
|
integer :: i
|
|
|
|
if (isize < 2) then
|
|
|
|
n = 1
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2017-04-14 18:11:02 +02:00
|
|
|
if (x(1) >= x(2)) then
|
2017-04-14 15:04:29 +02:00
|
|
|
n=1
|
|
|
|
else
|
|
|
|
n=0
|
|
|
|
endif
|
|
|
|
|
|
|
|
do i=2,isize
|
2017-04-19 15:31:12 +02:00
|
|
|
if (x(i-1) <= x(i)) then
|
2017-04-14 15:04:29 +02:00
|
|
|
n=n+1
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
SUBST [ X, type ]
|
|
|
|
; real ;;
|
|
|
|
d ; double precision ;;
|
|
|
|
i ; integer ;;
|
|
|
|
i8 ; integer*8 ;;
|
|
|
|
i2 ; integer*2 ;;
|
|
|
|
END_TEMPLATE
|
|
|
|
|
2017-04-19 15:31:12 +02:00
|
|
|
!BEGIN_TEMPLATE
|
|
|
|
! subroutine $Xsort(x,iorder,isize)
|
|
|
|
! implicit none
|
|
|
|
! BEGIN_DOC
|
|
|
|
! ! Sort array x(isize).
|
|
|
|
! ! iorder in input should be (1,2,3,...,isize), and in output
|
|
|
|
! ! contains the new order of the elements.
|
|
|
|
! END_DOC
|
|
|
|
! integer,intent(in) :: isize
|
|
|
|
! $type,intent(inout) :: x(isize)
|
|
|
|
! integer,intent(inout) :: iorder(isize)
|
|
|
|
! integer :: n
|
|
|
|
! call sorted_$Xnumber(x,isize,n)
|
|
|
|
! if ( isize-n < 1000) then
|
|
|
|
! call insertion_$Xsort(x,iorder,isize)
|
|
|
|
! else
|
|
|
|
! call heap_$Xsort(x,iorder,isize)
|
|
|
|
! endif
|
|
|
|
! end subroutine $Xsort
|
|
|
|
!
|
|
|
|
!SUBST [ X, type ]
|
|
|
|
! ; real ;;
|
|
|
|
! d ; double precision ;;
|
|
|
|
!END_TEMPLATE
|
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
BEGIN_TEMPLATE
|
2014-04-01 18:37:27 +02:00
|
|
|
subroutine $Xsort(x,iorder,isize)
|
|
|
|
implicit none
|
2014-04-07 20:01:30 +02:00
|
|
|
BEGIN_DOC
|
|
|
|
! Sort array x(isize).
|
|
|
|
! iorder in input should be (1,2,3,...,isize), and in output
|
|
|
|
! contains the new order of the elements.
|
|
|
|
END_DOC
|
2016-02-19 00:20:28 +01:00
|
|
|
integer,intent(in) :: isize
|
2014-04-07 20:01:30 +02:00
|
|
|
$type,intent(inout) :: x(isize)
|
|
|
|
integer,intent(inout) :: iorder(isize)
|
2017-04-14 15:04:29 +02:00
|
|
|
integer :: n
|
2017-04-14 18:11:02 +02:00
|
|
|
call sorted_$Xnumber(x,isize,n)
|
2017-04-19 15:31:12 +02:00
|
|
|
if (isize == n) then
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
if ( isize < 512+n) then
|
2014-04-01 18:37:27 +02:00
|
|
|
call insertion_$Xsort(x,iorder,isize)
|
|
|
|
else
|
2017-04-19 15:31:12 +02:00
|
|
|
call $Yradix_sort(x,iorder,isize,-1)
|
2014-04-01 18:37:27 +02:00
|
|
|
endif
|
|
|
|
end subroutine $Xsort
|
|
|
|
|
2017-04-19 15:31:12 +02:00
|
|
|
SUBST [ X, type, Y ]
|
|
|
|
; real ; i ;;
|
|
|
|
d ; double precision ; i8 ;;
|
2017-04-17 22:55:59 +02:00
|
|
|
END_TEMPLATE
|
|
|
|
|
|
|
|
BEGIN_TEMPLATE
|
|
|
|
subroutine $Xsort(x,iorder,isize)
|
|
|
|
implicit none
|
|
|
|
BEGIN_DOC
|
|
|
|
! Sort array x(isize).
|
|
|
|
! iorder in input should be (1,2,3,...,isize), and in output
|
|
|
|
! contains the new order of the elements.
|
|
|
|
END_DOC
|
|
|
|
integer,intent(in) :: isize
|
|
|
|
$type,intent(inout) :: x(isize)
|
|
|
|
integer,intent(inout) :: iorder(isize)
|
|
|
|
integer :: n
|
|
|
|
call $Xradix_sort(x,iorder,isize,-1)
|
|
|
|
end subroutine $Xsort
|
|
|
|
|
|
|
|
SUBST [ X, type ]
|
2014-04-01 18:37:27 +02:00
|
|
|
i ; integer ;;
|
|
|
|
i8 ; integer*8 ;;
|
|
|
|
i2 ; integer*2 ;;
|
|
|
|
END_TEMPLATE
|
|
|
|
|
|
|
|
BEGIN_TEMPLATE
|
|
|
|
subroutine $Xset_order(x,iorder,isize)
|
|
|
|
implicit none
|
2014-04-07 20:01:30 +02:00
|
|
|
BEGIN_DOC
|
|
|
|
! array A has already been sorted, and iorder has contains the new order of
|
|
|
|
! elements of A. This subroutine changes the order of x to match the new order of A.
|
|
|
|
END_DOC
|
|
|
|
integer :: isize
|
|
|
|
$type :: x(*)
|
|
|
|
$type,allocatable :: xtmp(:)
|
|
|
|
integer :: iorder(*)
|
|
|
|
integer :: i
|
|
|
|
|
|
|
|
allocate(xtmp(isize))
|
2014-04-01 18:37:27 +02:00
|
|
|
do i=1,isize
|
2014-04-07 20:01:30 +02:00
|
|
|
xtmp(i) = x(iorder(i))
|
2014-04-01 18:37:27 +02:00
|
|
|
enddo
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2014-04-01 18:37:27 +02:00
|
|
|
do i=1,isize
|
2014-04-07 20:01:30 +02:00
|
|
|
x(i) = xtmp(i)
|
2014-04-01 18:37:27 +02:00
|
|
|
enddo
|
2014-04-07 20:01:30 +02:00
|
|
|
deallocate(xtmp)
|
2014-04-01 18:37:27 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
SUBST [ X, type ]
|
|
|
|
; real ;;
|
|
|
|
d ; double precision ;;
|
|
|
|
i ; integer ;;
|
|
|
|
i8; integer*8 ;;
|
|
|
|
i2; integer*2 ;;
|
|
|
|
END_TEMPLATE
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_TEMPLATE
|
|
|
|
subroutine insertion_$Xsort_big (x,iorder,isize)
|
|
|
|
implicit none
|
2014-04-07 20:01:30 +02:00
|
|
|
BEGIN_DOC
|
|
|
|
! Sort array x(isize) using the insertion sort algorithm.
|
|
|
|
! iorder in input should be (1,2,3,...,isize), and in output
|
|
|
|
! contains the new order of the elements.
|
|
|
|
! This is a version for very large arrays where the indices need
|
|
|
|
! to be in integer*8 format
|
|
|
|
END_DOC
|
2016-02-19 00:20:28 +01:00
|
|
|
integer*8,intent(in) :: isize
|
2014-04-07 20:01:30 +02:00
|
|
|
$type,intent(inout) :: x(isize)
|
|
|
|
integer*8,intent(inout) :: iorder(isize)
|
|
|
|
$type :: xtmp
|
|
|
|
integer*8 :: i, i0, j, jmax
|
|
|
|
|
2014-04-01 18:37:27 +02:00
|
|
|
do i=1_8,isize
|
2014-04-07 20:01:30 +02:00
|
|
|
xtmp = x(i)
|
|
|
|
i0 = iorder(i)
|
|
|
|
j = i-1_8
|
|
|
|
do j=i-1_8,1_8,-1_8
|
|
|
|
if ( x(j) > xtmp ) then
|
|
|
|
x(j+1_8) = x(j)
|
|
|
|
iorder(j+1_8) = iorder(j)
|
|
|
|
else
|
|
|
|
exit
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
x(j+1_8) = xtmp
|
|
|
|
iorder(j+1_8) = i0
|
2014-04-01 18:37:27 +02:00
|
|
|
enddo
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2017-01-31 21:48:47 +01:00
|
|
|
end subroutine insertion_$Xsort_big
|
2014-04-01 18:37:27 +02:00
|
|
|
|
|
|
|
subroutine $Xset_order_big(x,iorder,isize)
|
|
|
|
implicit none
|
2014-04-07 20:01:30 +02:00
|
|
|
BEGIN_DOC
|
|
|
|
! array A has already been sorted, and iorder has contains the new order of
|
|
|
|
! elements of A. This subroutine changes the order of x to match the new order of A.
|
|
|
|
! This is a version for very large arrays where the indices need
|
|
|
|
! to be in integer*8 format
|
|
|
|
END_DOC
|
|
|
|
integer*8 :: isize
|
|
|
|
$type :: x(*)
|
|
|
|
$type, allocatable :: xtmp(:)
|
|
|
|
integer*8 :: iorder(*)
|
|
|
|
integer*8 :: i
|
|
|
|
allocate(xtmp(isize))
|
2014-04-01 18:37:27 +02:00
|
|
|
do i=1_8,isize
|
2014-04-07 20:01:30 +02:00
|
|
|
xtmp(i) = x(iorder(i))
|
2014-04-01 18:37:27 +02:00
|
|
|
enddo
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2014-04-01 18:37:27 +02:00
|
|
|
do i=1_8,isize
|
2014-04-07 20:01:30 +02:00
|
|
|
x(i) = xtmp(i)
|
2014-04-01 18:37:27 +02:00
|
|
|
enddo
|
|
|
|
deallocate(xtmp)
|
|
|
|
end
|
|
|
|
|
|
|
|
SUBST [ X, type ]
|
|
|
|
; real ;;
|
|
|
|
d ; double precision ;;
|
|
|
|
i ; integer ;;
|
|
|
|
i8; integer*8 ;;
|
|
|
|
i2; integer*2 ;;
|
|
|
|
END_TEMPLATE
|
|
|
|
|
|
|
|
BEGIN_TEMPLATE
|
|
|
|
|
2014-04-07 20:01:30 +02:00
|
|
|
recursive subroutine $Xradix_sort$big(x,iorder,isize,iradix)
|
|
|
|
implicit none
|
|
|
|
BEGIN_DOC
|
|
|
|
! Sort integer array x(isize) using the radix sort algorithm.
|
|
|
|
! iorder in input should be (1,2,3,...,isize), and in output
|
|
|
|
! contains the new order of the elements.
|
|
|
|
! iradix should be -1 in input.
|
|
|
|
END_DOC
|
2017-04-12 20:23:04 +02:00
|
|
|
integer*$int_type, intent(in) :: isize
|
|
|
|
integer*$int_type, intent(inout) :: iorder(isize)
|
|
|
|
integer*$type, intent(inout) :: x(isize)
|
2014-04-07 20:01:30 +02:00
|
|
|
integer, intent(in) :: iradix
|
|
|
|
integer :: iradix_new
|
2017-04-12 20:23:04 +02:00
|
|
|
integer*$type, allocatable :: x2(:), x1(:)
|
2017-04-17 22:55:59 +02:00
|
|
|
integer*$type :: i4 ! data type
|
2017-04-12 20:23:04 +02:00
|
|
|
integer*$int_type, allocatable :: iorder1(:),iorder2(:)
|
2017-04-17 22:55:59 +02:00
|
|
|
integer*$int_type :: i0, i1, i2, i3, i ! index type
|
2017-04-12 20:23:04 +02:00
|
|
|
integer*$type :: mask
|
2017-04-17 22:55:59 +02:00
|
|
|
integer :: err
|
2014-04-07 20:01:30 +02:00
|
|
|
!DIR$ ATTRIBUTES ALIGN : 128 :: iorder1,iorder2, x2, x1
|
2014-04-01 18:37:27 +02:00
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
if (iradix == -1) then ! Sort Positive and negative
|
|
|
|
|
|
|
|
allocate(x1(isize),iorder1(isize), x2(isize),iorder2(isize),stat=err)
|
|
|
|
if (err /= 0) then
|
|
|
|
print *, irp_here, ': Unable to allocate arrays'
|
|
|
|
stop
|
|
|
|
endif
|
|
|
|
|
|
|
|
i1=1_$int_type
|
|
|
|
i2=1_$int_type
|
|
|
|
do i=1_$int_type,isize
|
|
|
|
if (x(i) < 0_$type) then
|
|
|
|
iorder1(i1) = iorder(i)
|
|
|
|
x1(i1) = -x(i)
|
|
|
|
i1 = i1+1_$int_type
|
|
|
|
else
|
|
|
|
iorder2(i2) = iorder(i)
|
|
|
|
x2(i2) = x(i)
|
|
|
|
i2 = i2+1_$int_type
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
i1=i1-1_$int_type
|
|
|
|
i2=i2-1_$int_type
|
|
|
|
|
|
|
|
do i=1_$int_type,i2
|
|
|
|
iorder(i1+i) = iorder2(i)
|
|
|
|
x(i1+i) = x2(i)
|
|
|
|
enddo
|
|
|
|
deallocate(x2,iorder2,stat=err)
|
|
|
|
if (err /= 0) then
|
|
|
|
print *, irp_here, ': Unable to deallocate arrays x2, iorder2'
|
|
|
|
stop
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
|
|
if (i1 > 1_$int_type) then
|
|
|
|
call $Xradix_sort$big(x1,iorder1,i1,-2)
|
|
|
|
do i=1_$int_type,i1
|
|
|
|
x(i) = -x1(1_$int_type+i1-i)
|
|
|
|
iorder(i) = iorder1(1_$int_type+i1-i)
|
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
deallocate(x1,iorder1,stat=err)
|
|
|
|
if (err /= 0) then
|
|
|
|
print *, irp_here, ': Unable to deallocate arrays x1, iorder1'
|
|
|
|
stop
|
|
|
|
endif
|
|
|
|
|
|
|
|
if (i2>1_$int_type) then
|
|
|
|
call $Xradix_sort$big(x(i1+1_$int_type),iorder(i1+1_$int_type),i2,-2)
|
|
|
|
endif
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
else if (iradix == -2) then ! Positive
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2014-04-01 18:37:27 +02:00
|
|
|
! Find most significant bit
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2017-04-12 20:23:04 +02:00
|
|
|
i0 = 0_$int_type
|
2017-04-17 22:55:59 +02:00
|
|
|
i4 = maxval(x)
|
2017-04-19 15:31:12 +02:00
|
|
|
if (i4 == 0_$type) then
|
|
|
|
return
|
|
|
|
endif
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
iradix_new = $integer_size-1-leadz(i4)
|
2017-04-12 20:23:04 +02:00
|
|
|
mask = ibset(0_$type,iradix_new)
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
allocate(x1(isize),iorder1(isize), x2(isize),iorder2(isize),stat=err)
|
2014-04-01 18:37:27 +02:00
|
|
|
if (err /= 0) then
|
2014-04-07 20:01:30 +02:00
|
|
|
print *, irp_here, ': Unable to allocate arrays'
|
|
|
|
stop
|
2014-04-01 18:37:27 +02:00
|
|
|
endif
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2017-04-12 20:23:04 +02:00
|
|
|
i1=1_$int_type
|
|
|
|
i2=1_$int_type
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
do i=1_$int_type,isize
|
2017-04-12 20:23:04 +02:00
|
|
|
if (iand(mask,x(i)) == 0_$type) then
|
2014-04-01 18:37:27 +02:00
|
|
|
iorder1(i1) = iorder(i)
|
|
|
|
x1(i1) = x(i)
|
2017-04-12 20:23:04 +02:00
|
|
|
i1 = i1+1_$int_type
|
2014-04-01 18:37:27 +02:00
|
|
|
else
|
|
|
|
iorder2(i2) = iorder(i)
|
|
|
|
x2(i2) = x(i)
|
2017-04-12 20:23:04 +02:00
|
|
|
i2 = i2+1_$int_type
|
2014-04-01 18:37:27 +02:00
|
|
|
endif
|
|
|
|
enddo
|
2017-04-12 20:23:04 +02:00
|
|
|
i1=i1-1_$int_type
|
|
|
|
i2=i2-1_$int_type
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
do i=1_$int_type,i1
|
2014-04-01 18:37:27 +02:00
|
|
|
iorder(i0+i) = iorder1(i)
|
|
|
|
x(i0+i) = x1(i)
|
|
|
|
enddo
|
|
|
|
i0 = i0+i1
|
|
|
|
i3 = i0
|
|
|
|
deallocate(x1,iorder1,stat=err)
|
|
|
|
if (err /= 0) then
|
2014-04-07 20:01:30 +02:00
|
|
|
print *, irp_here, ': Unable to deallocate arrays x1, iorder1'
|
|
|
|
stop
|
2014-04-01 18:37:27 +02:00
|
|
|
endif
|
2014-04-07 20:01:30 +02:00
|
|
|
|
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
do i=1_$int_type,i2
|
2014-04-01 18:37:27 +02:00
|
|
|
iorder(i0+i) = iorder2(i)
|
|
|
|
x(i0+i) = x2(i)
|
|
|
|
enddo
|
|
|
|
i0 = i0+i2
|
|
|
|
deallocate(x2,iorder2,stat=err)
|
|
|
|
if (err /= 0) then
|
2014-04-07 20:01:30 +02:00
|
|
|
print *, irp_here, ': Unable to deallocate arrays x2, iorder2'
|
|
|
|
stop
|
2014-04-01 18:37:27 +02:00
|
|
|
endif
|
2014-04-07 20:01:30 +02:00
|
|
|
|
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
if (i3>1_$int_type) then
|
2014-04-01 18:37:27 +02:00
|
|
|
call $Xradix_sort$big(x,iorder,i3,iradix_new-1)
|
|
|
|
endif
|
2014-04-07 20:01:30 +02:00
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
if (isize-i3>1_$int_type) then
|
|
|
|
call $Xradix_sort$big(x(i3+1_$int_type),iorder(i3+1_$int_type),isize-i3,iradix_new-1)
|
2014-04-01 18:37:27 +02:00
|
|
|
endif
|
2014-04-07 20:01:30 +02:00
|
|
|
|
|
|
|
return
|
|
|
|
endif
|
2014-04-01 18:37:27 +02:00
|
|
|
|
2014-05-13 13:57:58 +02:00
|
|
|
ASSERT (iradix >= 0)
|
|
|
|
|
2014-04-07 20:01:30 +02:00
|
|
|
if (isize < 48) then
|
|
|
|
call insertion_$Xsort$big(x,iorder,isize)
|
2014-04-01 18:37:27 +02:00
|
|
|
return
|
2014-04-07 20:01:30 +02:00
|
|
|
endif
|
2014-04-01 18:37:27 +02:00
|
|
|
|
|
|
|
|
2014-04-07 20:01:30 +02:00
|
|
|
allocate(x2(isize),iorder2(isize),stat=err)
|
|
|
|
if (err /= 0) then
|
|
|
|
print *, irp_here, ': Unable to allocate arrays x1, iorder1'
|
|
|
|
stop
|
|
|
|
endif
|
2014-04-01 18:37:27 +02:00
|
|
|
|
|
|
|
|
2017-04-12 20:23:04 +02:00
|
|
|
mask = ibset(0_$type,iradix)
|
2017-04-17 22:55:59 +02:00
|
|
|
i0=1_$int_type
|
|
|
|
i1=1_$int_type
|
2014-04-01 18:37:27 +02:00
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
do i=1_$int_type,isize
|
2017-04-12 20:23:04 +02:00
|
|
|
if (iand(mask,x(i)) == 0_$type) then
|
2014-04-07 20:01:30 +02:00
|
|
|
iorder(i0) = iorder(i)
|
|
|
|
x(i0) = x(i)
|
2017-04-17 22:55:59 +02:00
|
|
|
i0 = i0+1_$int_type
|
2014-04-07 20:01:30 +02:00
|
|
|
else
|
|
|
|
iorder2(i1) = iorder(i)
|
|
|
|
x2(i1) = x(i)
|
2017-04-17 22:55:59 +02:00
|
|
|
i1 = i1+1_$int_type
|
2014-04-07 20:01:30 +02:00
|
|
|
endif
|
|
|
|
enddo
|
2017-04-17 22:55:59 +02:00
|
|
|
i0=i0-1_$int_type
|
|
|
|
i1=i1-1_$int_type
|
2014-04-01 18:37:27 +02:00
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
do i=1_$int_type,i1
|
2014-04-07 20:01:30 +02:00
|
|
|
iorder(i0+i) = iorder2(i)
|
|
|
|
x(i0+i) = x2(i)
|
|
|
|
enddo
|
2014-04-01 18:37:27 +02:00
|
|
|
|
2014-04-07 20:01:30 +02:00
|
|
|
deallocate(x2,iorder2,stat=err)
|
|
|
|
if (err /= 0) then
|
|
|
|
print *, irp_here, ': Unable to allocate arrays x2, iorder2'
|
|
|
|
stop
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
|
|
if (iradix == 0) then
|
|
|
|
return
|
|
|
|
endif
|
2014-04-01 18:37:27 +02:00
|
|
|
|
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
if (i1>1_$int_type) then
|
|
|
|
call $Xradix_sort$big(x(i0+1_$int_type),iorder(i0+1_$int_type),i1,iradix-1)
|
2014-04-07 20:01:30 +02:00
|
|
|
endif
|
|
|
|
if (i0>1) then
|
|
|
|
call $Xradix_sort$big(x,iorder,i0,iradix-1)
|
|
|
|
endif
|
2014-04-01 18:37:27 +02:00
|
|
|
|
2014-04-07 20:01:30 +02:00
|
|
|
end
|
2014-04-01 18:37:27 +02:00
|
|
|
|
2017-04-17 22:55:59 +02:00
|
|
|
SUBST [ X, type, integer_size, is_big, big, int_type ]
|
2017-04-12 20:23:04 +02:00
|
|
|
i ; 4 ; 32 ; .False. ; ; 4 ;;
|
2017-04-17 22:55:59 +02:00
|
|
|
i8 ; 8 ; 64 ; .False. ; ; 4 ;;
|
|
|
|
i2 ; 2 ; 16 ; .False. ; ; 4 ;;
|
|
|
|
i ; 4 ; 32 ; .True. ; _big ; 8 ;;
|
2017-04-12 20:23:04 +02:00
|
|
|
i8 ; 8 ; 64 ; .True. ; _big ; 8 ;;
|
2014-04-01 18:37:27 +02:00
|
|
|
END_TEMPLATE
|
|
|
|
|
|
|
|
|