我们可以在 Fortran 中创建生成随机数的纯函数吗?

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

我的目标是使用可在 DO CONCURRENT 结构中使用的随机数编写一个纯函数。编译器似乎不允许这样做。

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.

为什么会这样,有没有办法在纯例程中生成随机数?

MWE 紧随其后。编译命令为gfortran mwe.f95。编译器版本是 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

这完全违背了纯粹的概念。真正的纯函数,正如在真正的函数式语言中所发现的那样,对于相同的输入应该总是 return 相同的结果。 Fortran 纯函数可以读取模块变量,因此更复杂。

对 return 伪随机数使用任何函数(不仅仅是纯函数)甚至不是一个好主意。当表达式中有更多函数调用时,允许 Fortran 编译器只对函数求值一次。当该函数是纯函数时,这种情况更有可能或更合理。

我建议只使用常规 DO 循环并调用 random_number 或其他自定义 PRNG 子例程。即使您想要自动并行化或类似的,编译器通常也能够像处理 DO CONCURRENT 一样处理常规 DO 循环。

您需要纯随机数生成器。很可能,比如说,对于线性同余生成器,其中种子(是 64 位无符号整数)与状态相同并且与 return 值相同。在那种情况下 state/seed 被保存在采样例程之外,显式传递并在从 RNG 取回时被存储