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

时间:2015-09-17 17:44:47

标签: random concurrency fortran gfortran

我的目标是使用可以在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

2 个答案:

答案 0 :(得分:5)

这完全违背了纯粹的概念。真正的纯函数,如真正的函数式语言,应该始终为相同的输入返回相同的结果。 Fortran纯函数可以读取模块变量,因此更复杂。

使用任何函数(而不仅仅是纯函数)来返回伪随机数甚至都不是一个好主意。当在表达式中有更多函数调用时,允许Fortran编译器仅对该函数进行一次求值。当这个功能是纯粹的时候,这更有可能或更有道理。

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

答案 1 :(得分:1)

你需要纯随机数发生器。例如,很可能为线性同余生成器做出种子(64位无符号整数)与状态相同并且与返回值相同。在这种情况下,状态/种子保持在采样例程之外,明确传递并从RNG返回存储