gfortran和随机数

5

我正在尝试使用mac-ports (OS-X)中的Gfortran 4.7编译以下简单代码:

program main

implicit none

integer :: n = 1, clock, i

integer, dimension(1) :: iseed

! initialize the random number generator
call random_seed(size = n)

call system_clock(COUNT=clock)

iseed = clock + 37 * (/ (i - 1, i = 1, n) /)
! iseed = clock
! iseed = abs( mod((clock*181)*((1-83)*359), 104729) )
call random_seed(PUT = iseed)

end program main

并且出现了这个错误:

gfortran-mp-4.7  tmp.f90
tmp.f90:17.23:

call random_seed(PUT = iseed)
                   1
Error: Size of 'put' argument of 'random_seed' intrinsic at (1) too small (1/12)

我完全不使用Fortran(我是C++开发人员),所以真的很感谢有人能帮忙使其正常工作。

p.s. 在类似问题上,我发现了几篇论坛文章,当前未注释的解决方案类似于此GCC错误报告中提到的

这个stackoverflow帖子中提到了使用abs的方法(我没有运行并行程序,因此没有加PID)。

更新:

以下方式可行:

program main

implicit none

integer :: n = 12, clock, i

integer, dimension(:), allocatable :: iseed

! initialize the random number generator
allocate(iseed(n))
call random_seed(size = n)

call system_clock(COUNT=clock)

iseed = clock + 37 * [(i, i = 0,n-1)]
call random_seed(PUT = iseed)

end program main

你链接的GCC错误报告中已经给出了解决方案:你需要设置n = 12integer,dimension(12):: iseedrandom_seed函数的put参数需要一个由12个整数组成的数组。 - Yossarian
1个回答

9

稍微详细一些,这个

call random_seed(size = n)

n中返回您必须使用的秩为1的整数数组的大小,如果要初始化RNG。我建议通过更改其声明使iseed可分配:

integer, dimension(:), allocatable :: iseed

然后,在获取 n 的值之后,分配它:
allocate(iseed(n))

将它填充上你喜欢的值,然后使用put进行操作。

你可以尝试使用以下语句一次性分配并填充:

allocate(iseed(n), source = clock + 37 * [(i, i = 0,n-1)])

我使用“可能”这个词是因为这取决于你的编译器是否更新。

在 OP 的评论后进行编辑

不,你还没有完全理解我的建议。

通过执行以下命令获取 n 的值:

call random_seed(size = n)

不要将n初始化为12。

然后分配数组并填充它,可以使用源分配一条语句完成,或者使用allocate语句后跟一个赋值语句来完成。

在...

allocate(iseed(n))
call random_seed(size = n)

操作顺序不正确。 这会将iseed设置为12个元素(即在执行第一个语句时n的值),然后将n设置为RNG所需的数组大小。 只要它是12,您就不会看到任何问题,但是一旦您将代码移植到另一个编译器,甚至可能是同一编译器的另一个版本,您就会冒着遇到需要不同大小整数数组的RNG的风险。 没有必要将一个值硬编码到您的代码中,因此请勿这样做。

谢谢您的回复。我已经放置了更新代码,这是您所说的吗?它可以成功编译。 - Denis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接