dantopa
dantopa

Reputation: 635

Can we create pure functions in Fortran which generate random numbers?

My goal is to write a pure function using random numbers which can be used in a DO CONCURRENT structure. The compiler does not seem to permit this.

mwe.f95:8:30:

             call init_seed ( )
                              1
Error: Subroutine call to ‘init_seed’ at (1) is not PURE
mwe.f95:9:36:

             call random_number ( y )
                                    1
Error: Subroutine call to intrinsic ‘random_number’ at (1) is not PURE
mwe.f95:16:8:

     use myFunction
        1
Fatal Error: Can't open module file ‘myfunction.mod’ for reading at (1): No such file or directory
compilation terminated.

Why is this so and is there a way to generate random numbers in a pure routine?

The MWE follows. Compilation command is gfortran mwe.f95. Compiler version is GCC 5.1.0.

module myFunction

    implicit none

contains
    pure real function action ( ) result ( new_number )
        real :: y
            call init_seed ( )
            call random_number ( y )
            new_number = y**2
    end function
end module myFunction


program mwe
    use myFunction
    implicit none
    real :: x

        x = action ( )

end program mwe

Upvotes: 1

Views: 779

Answers (2)

Severin Pappadeux
Severin Pappadeux

Reputation: 20080

You'll need pure random number generator. It is quite possible to make, say, for Linear Congruential Generator, where seed (being 64bit unsigned integer) is the same as state and is the same as return value. In that case state/seed is kept externally outside the sampling routine, passed explicitly and on getting it back from RNG is stored

Upvotes: 1

This is completely against the concept of pureness. True pure functions, as found in true functional languages, should always return the same result for the same input. Fortran pure functions can read module variables and therefore are more complex.

It is not even a good idea to have any function, not just a pure function, to return pseudo-random numbers. When you have more function calls in an expression the Fortran compiler is permitted to evaluate the function just once. That is even more likely, or better justified, when that function is pure.

I would suggest to just use regular DO loops and call random_number or other custom PRNG subroutine. Even if you want automatic parallelization or similar , the compilers are normally capable to treat regular DO loops equally well as DO CONCURRENT.

Upvotes: 5

Related Questions