gfortran 和随机数 [英] gfortran and random numbers

查看:17
本文介绍了gfortran 和随机数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to compile the following simple code using Gfortran 4.7 from mac-ports (OS-X):

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++ 人),所以如果有人能提供帮助并使其正常工作,我将不胜感激.

I don't use Fortran at all (I am a C++ guy), so would really appreciate if someone could help and make it working.

附言在一个类似的问题上,我发现了几个论坛帖子,当前取消注释的解决方案类似于 这个 GCC 错误报告.

p.s. On a similar issue i found couple of forum posts, the current uncomment solution is similar to the one mentioned in this GCC bug report.

在此堆栈溢出中 提到了带有 abs 的那个发布(添加它没有PID,因为我无论如何都不并行运行.

The one with abs is mentioned in this stack overflow post (added it without PID since i don't run in parallel anyway.

更新:

以下作品:

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

推荐答案

为了放大@Yossarian 的评论,这个

To amplify somewhat on @Yossarian's comment, this

call random_seed(size = n)

n 中返回要初始化 RNG 时必须使用的 rank 1 整数数组的大小.我建议通过将其声明更改为 iseed 来分配:

returns, in n, the size of the rank 1 integer array that you have to use if you want to initialise the RNG. I'd suggest making iseed allocatable by changing its declaration to:

integer, dimension(:), allocatable :: iseed

然后,在获得 n 的值后,分配它:

then, after getting a value for n, allocate it:

allocate(iseed(n))

用你喜欢的值填充它,然后put它.

populate it with your favourite values, then put it.

您也许可以在这样的一个语句中分配和填充它:

You might be able to allocate and populate it in one statement like this:

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

我写可能,因为这取决于你的编译器的最新程度.

I write might because this depends on how up to date your compiler is.

编辑,在 OP 评论之后

EDIT, after OP comment

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

No, you have not quite understood what I suggested.

通过执行获取n的值

call random_seed(size = n)

不要将 n 初始化为 12.

don't initialise n to 12.

然后在一个语句(使用源分配)或一个 allocate 语句后跟一个赋值语句中分配数组并填充它.

Then allocate the array and populate it, either in one statement (using sourced allocation) or an allocate statement followed by an assignment.

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

操作顺序不正确.这将 iseed 设置为 12 个元素(即执行第一条语句时 n 的值),然后将 n 设置为大小RNG 所需的数组.只要那是 12,您就不会看到任何问题,但是一旦您将代码移植到另一个编译器,甚至可能是同一编译器的另一个版本,您就有可能遇到需要不同大小的整数数组的 RNG.无需将值硬连线到您的代码中,所以不要.

the sequence of operations is incorrect. This sets iseed to have 12 elements (which is the value of n when the first statement is executed), and then sets n to the size of the array required by the RNG. So long as that is 12 you won't see any problems, but as soon as you port your code to another compiler, possibly even another version of the same compiler, you risk running into an RNG which requires an integer array of a different size. There is no need to hardwire a value into your code, so don't.

这篇关于gfortran 和随机数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆