我的目标是使用可以在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
答案 0 :(得分:5)
这完全违背了纯粹的概念。真正的纯函数,如真正的函数式语言,应该始终为相同的输入返回相同的结果。 Fortran纯函数可以读取模块变量,因此更复杂。
使用任何函数(而不仅仅是纯函数)来返回伪随机数甚至都不是一个好主意。当在表达式中有更多函数调用时,允许Fortran编译器仅对该函数进行一次求值。当这个功能是纯粹的时候,这更有可能或更有道理。
我建议只使用常规DO循环并调用random_number
或其他自定义PRNG子例程。即使您想要自动并行化或类似,编译器通常也能够像DO CONCURRENT一样处理常规DO循环。
答案 1 :(得分:1)
你需要纯随机数发生器。例如,很可能为线性同余生成器做出种子(64位无符号整数)与状态相同并且与返回值相同。在这种情况下,状态/种子保持在采样例程之外,明确传递并从RNG返回存储