首页 > 解决方案 > 在 Fortran 中生成随机数

问题描述

我用 Fortran 写了一个基于统计的代码。生成随机数变量对于采样是必要的。我在相同的代码之间搜索(以找到有效的结构)并看到他们在其中使用了“RANDOM_SEED”命令。我在网上搜索以找到可以帮助我执行此命令的内容,然后找到:RANDOM_SEED。但我并没有从中得到什么。另外,我在这个站点上搜索并发现:random_number() 在 GNU 和 PGI Fortran 编译器之间给出了截然不同的行为。我发现 Fortran 创建的是伪随机数,而不是真正的随机数。


问题是什么?

伪随机数和“RANDOM_SEED”命令有什么关系?

Fortran 中的随机数是否存在于某些批次中,并且此命令会更改批次或从一开始就忽略某些数字以避免创建相同的随机数?

我也找到“SET_SEED”,这个命令是什么?

“RANDOM_SEED”命令中的“ size ”、“ put ”和“ give ”到底是什么?

我会感谢任何给我一点帮助的评论,并原谅我写的缺点。

标签: fortranrandom-seed

解决方案


伪随机生成器都以类似的方式使用。它们生成一个确定的数字序列。当您有一个起点时,您可以生成下一个伪随机数,然后生成下一个伪随机数,然后......

什么RANDOM_SEED()是设置序列的这个起点。然后调用RANDOM_NUMBER()会生成序列中的数字。


参数的含义RANDOM_SEED()只是技术细节,由 Fortran 标准给出,并在许多编译器的手册中进行了描述,例如gfortran 手册

   CALL RANDOM_SEED([SIZE, PUT, GET])  

Arguments: 
 
   SIZE (Optional) Shall be a scalar and of type default INTEGER, with INTENT(OUT). It specifies the minimum size of the arrays used with the PUT and GET arguments. 
 
   PUT  (Optional) Shall be an array of type default INTEGER and rank one. It is INTENT(IN) and the size of the array must be larger than or equal to the number returned by the SIZE argument. 
 
   GET  (Optional) Shall be an array of type default INTEGER and rank one. It is INTENT(OUT) and the size of the array must be larger than or equal to the number returned by the SIZE argument.

实际上,and 的实际技术含义put取决于get内部结构,并且在不同的编译器版本之间会有所不同。它们是integer数组,并size告诉您这些数组有多大。

您主要关心的是为您放入的数字提供足够的熵(一些“随机”位)put。它只是一个整数数组,用于设置该序列的起点。get用于接收伪随机序列的当前状态。

请注意,您也可以完全RANDOM_SEED()不带任何参数调用,结果取决于实现,但通常会随机化起点。检查编译器版本的手册。

有关简单示例,请参阅链接的gfortran 手册

program test_random_seed
  implicit none
  integer, allocatable :: seed(:)
  integer :: n

  call random_seed(size = n)
  allocate(seed(n))
  call random_seed(get=seed)
  write (*, *) seed
end program test_random_seed

您没有要求它,但如果您的编译器足够新,例如 gfortran 9 或更高版本,它可能支持 Fortran 2018 intrinsic subroutine RANDOM_INIT()

它有两个逻辑论证。

call RANDOM_INIT(repeatable, image_distinct)

论据

repeatable- 如果为 .true.,则种子设置为依赖于处理器的值,每次从同一图像调用 random_init 时该值相同。如果为 .false.,则种子设置为依赖于处理器的值。
image_distinct- 主要用于 coarray 并行程序,请参阅链接中的描述

所以你可以call RANDOM_INIT(.false.,.true.)将伪随机序列设置为一些随机的初始状态。


SET_SEED与不同的过时生成器一起使用,请忽略它。


推荐阅读