RANPER Subroutine

public subroutine RANPER(N, Istart, X)

NAME

ranper(3f) - [M_datapac:RANDOM] generates a random permutation

SYNOPSIS

   SUBROUTINE RANPER(N,Istart,X)

    INTEGER,intent(in)    :: N
    INTEGER,intent(inout) :: Istart
    REAL(kind=wp)         :: X(:)

DESCRIPTION

RANPER(3f) generates a random permutation of size N of the values 1.0,
2.0, 3.0, ..., N-1, N.

INPUT ARGUMENTS

N       The desired integer size of the random 1 to N permutation.

ISTART  An integer flag code which (if set to 0) will start the
        generator over and hence produce the same random permutation
        over and over again upon successive calls to this subroutine
        within a run; or (if set to some integer value not equal to 0,
        like, say, 1) will allow the generator to continue from where
        it stopped and hence produce different random permutations
        upon successive calls to this subroutine within a run.

OUTPUT ARGUMENTS

X     A vector (of dimension at least N) into which the generated
      random permutation will be placed of size N of the values 1.0,
      2.0, 3.0, ..., n-1, n.

EXAMPLES

Sample program:

program demo_ranper
use M_datapac, only : ranper
implicit none
integer,parameter :: n=10
integer           :: istart
real              :: x(n)
integer           :: i
   do i=1,3
      istart=i
      call  RANPER(N,Istart,X)
      write(*,*)istart
      write(*,'(*(g0.2,1x))')x
   enddo
end program demo_ranper

AUTHOR

The original DATAPAC library was written by James Filliben of the
Statistical Engineering Division, National Institute of Standards
and Technology.

Algorithm suggested by Dan Lozier, National Bureau of Standards
(205.01).

MAINTAINER

John Urban, 2022.05.31

LICENSE

CC0-1.0

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: N
integer, intent(inout) :: Istart
real(kind=wp) :: X(:)

Source Code

SUBROUTINE RANPER(N,Istart,X)
INTEGER,intent(in)    :: N
INTEGER,intent(inout) :: Istart
REAL(kind=wp)         :: X(:)

INTEGER       :: i , iadd , j
REAL(kind=wp) :: add , an , hold , u(1)
INTEGER       :: iseed
!
      an = N
!
!     CHECK THE INPUT ARGUMENTS FOR ERRORS
!
   IF ( N<1 ) THEN
      WRITE (G_IO,99001)
      99001 FORMAT (' ***** FATAL ERROR--The first input argument to RANPER(3f) is non-positive *****')
      WRITE (G_IO,99002) N
      99002 FORMAT (' ***** The value of the argument is ',I0,' *****')
      RETURN
   ELSEIF ( N==1 ) THEN
      WRITE (G_IO,99003)
      99003 FORMAT (' ***** NON-FATAL DIAGNOSTIC--The first input argument to RANPER(3f) has the value 1 *****')
      X(1) = 1
      RETURN
   ELSE
      CALL UNIRAN(1,Istart,u)

      DO i = 1 , N
         X(i) = i
      ENDDO
      Iseed=1
      DO i = 1 , N
         CALL UNIRAN(1,iseed,u)
         add = an*u(1) + 1.0_wp
         iadd = add
         IF ( iadd<1 ) iadd = 1
         IF ( iadd>N ) iadd = N
         j = i + iadd
         IF ( j>N ) j = j - N
         hold = X(j)
         X(j) = X(i)
         X(i) = hold
      ENDDO
   ENDIF

END SUBROUTINE RANPER