0

I programmed a Knuth shuffle in Fortran as follows

subroutine knuth_shuffle(array, length)
    implicit none

    integer :: length
    integer :: array(length)

    integer :: randomIndex
    integer :: temp

    do i = 1, length - 2
        randomIndex = floor(randomBetween(real(i), real(length)))
        temp = array(i)
        array(i) = array(randomIndex)
        array(randomIndex) = temp
    enddo
end subroutine knuth_shuffle

Every time I call the subroutine I have to enter the array length too.

call knuth_shuffle(A, size(A))

Is there a way I can change the subroutine so when I call it, it looks more like:

call knuth_shuffle(A)
francescalus
  • 30,576
  • 16
  • 61
  • 96
Jake Love
  • 3
  • 1
  • @Yossarian, please don't do mass editing to remove tags without also looking at the post contents which may be amenable to improvements. – francescalus Dec 13 '17 at 11:03

1 Answers1

3

You could change

subroutine knuth_shuffle(array, length)
    implicit none

    integer :: length
    integer :: array(length)

    integer :: randomIndex
    integer :: temp

to

subroutine knuth_shuffle(array)
    implicit none

    integer :: array(:)

    integer :: length
    integer :: randomIndex
    integer :: temp

    length = size(array)

or you could just chuck away the local variable length and write

subroutine knuth_shuffle(array)
    implicit none

    integer :: array(:)

    integer :: randomIndex
    integer :: temp
    integer :: i

    do i = 1, size(array) - 2
        randomIndex = floor(randomBetween(real(i), real(size(array))))
        temp = array(i)
        array(i) = array(randomIndex)
        array(randomIndex) = temp
    enddo
end subroutine knuth_shuffle

While I'm answering: the subroutine doesn't know or care if the actual argument supplied as array is allocatable or static. There is nothing in the subroutine that is affected by, nor which affects, the allocation status of the array. From the subroutine's perspective array is of assumed-shape, on which point see this question and answer.

As @francescalus has commented, if it has assumed-shape array arguments the procedure requires an explicit interface The easy way to provide that is to have the compiler generate the interface; either (preferable) put the procedure in a module and use it or (more limited applicability) include it within the contains section of another program unit (maybe the main program unit). A last resort, generally only to be taken when modifying old code, would be to write an interface block yourself.

High Performance Mark
  • 77,191
  • 7
  • 105
  • 161