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

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

问题描述

我试图从mac-ports(OS-X)中使用Gfortran 4.7编译以下简单代码:

 程序主

隐含无

整数:: n = 1,时钟,
$ b整数,维(1):: iseed

!初始化随机数发生器
调用random_seed(size = n)

call system_clock(COUNT = clock)

iseed = clock + 37 *(/(i - 1,i = 1,n)/)
! iseed =时钟
! 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:

调用random_seed(PUT = iseed)
1
错误:大小(1)太小(1/12)



的'random_seed'我根本不使用Fortran(我是C ++的人),所以如果有人能够帮助并使之工作,我会非常感激。



ps在类似的问题上,我发现了几个论坛帖子,目前的解除评论解决方案与此GCC错误报告

提到 abs 的那个在这个堆栈溢出帖子(添加它没有PID,因为我并不是平行运行。



更新:

以下工作:

 程式main 

隐式无

整型:: n = 12,时钟,
$ b整型,维(:),allocatable :: iseed

!初始化随机数生成器
分配(iseed(n))
调用random_seed(size = n)

调用system_clock(COUNT = clock)

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

结束程序main


解决方案

要放大@Yossarian的评论,

 调用random_seed(size = n)

返回,在 n 中,等级1的大小int如果你想初始化RNG,你必须使用eger数组。我建议通过将其声明更改为:

 >来分配 iseed  integer,dimension(:),allocatable :: iseed 

然后,获取<$ c
$ b $ $ p $ allocate(iseed(n))

用您喜欢的值填充它,然后放入它。



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

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

我写了 might ,因为这取决于编译器的最新状态。

编辑OP comment



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



获取<$ c通过执行

$ p $ 调用random_seed(size = n)
来执行$ c> n
code>

不会初始化 n 至12。



然后分配数组并使用一个语句(使用来源分配)或一个分配语句,然后赋值。





 分配(iseed(n))
调用random_seed(size = n)

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


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

and have this error:

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)

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

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.

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

UPDATE:

the following works:

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

解决方案

To amplify somewhat on @Yossarian's comment, this

call random_seed(size = n)

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

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

allocate(iseed(n))

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.

EDIT, after OP comment

No, you have not quite understood what I suggested.

Get a value for n by executing

call random_seed(size = n)

don't initialise n to 12.

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

In

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

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天全站免登陆