Random 如何在fortran中生成一个随机函数,将相同的随机分布生成数组?
我想我下面的代码并没有给出相同的随机分布Random 如何在fortran中生成一个随机函数,将相同的随机分布生成数组?,random,fortran,fortran90,Random,Fortran,Fortran90,我想我下面的代码并没有给出相同的随机分布 subroutine trig_random_value() implicit none integer :: t, z, y, x real(real64) :: theta, r real(real64), parameter :: PI=4.D0*DATAN(1.D0) integer, dimension(12) :: date_time integer, dimension(12) :: see
subroutine trig_random_value()
implicit none
integer :: t, z, y, x
real(real64) :: theta, r
real(real64), parameter :: PI=4.D0*DATAN(1.D0)
integer, dimension(12) :: date_time
integer, dimension(12) :: seed
call date_and_time(values=date_time)
call random_seed
seed = date_time(6) * date_time(7) + date_time(8)
call random_seed(put = seed)
do z = 1, z_size
do y = 1, y_size
do x = 1, x_size
theta = rand()*2*PI
r = 0.1*rand()
l1(1, z, y, x) = r*cos(theta)
l2(1, z, y, x) = r*sin(theta)
theta = rand()*2*PI
r = 0.1*rand()
l1(2, z, y, x) = r*cos(theta)
l2(2, z, y, x) = r*sin(theta)
end do
end do
end do
return
end subroutine trig_random_value
根据我的代码,我尝试将随机值设置为l1(1,:,:,:,:)
,l1(2,:,:,:,:)
,l2(1,:,:,:,:,:)
,其中l(t,x,y,z)是(3+1)维数组
为什么我要用三角函数作为随机函数?因为我想要一个循环随机化。如果我绘制l1(1,:,:,:,:)与l2(1,:,:,:)或l1(2,:,:,:,:)与l2(2,:,,:,:)的分布,我将得到半径为0.1的圆形分布
那么,为什么我告诉你,这不完全是给我一个相同的分布?因为我试图测量它们的方差,结果
variance_l1_t1 = 1.6670507752921395E-003
variance_l1_t2 = 3.3313151655785292E-003
variance_l2_t1 = 4.9965623815717321E-003
variance_l2_t2 = 6.6641054728288360E-003
请注意,(方差_l1_t2-方差_l1_t1)=(方差_l2_t1-方差_l1_t2)=(方差_l2_t2-方差_l2_t1)=0.00166
这是一个很奇怪的结果。实际上我应该得到几乎相同的方差值l1(1,:,:,:)
,l1(2,:,:,:,:)
,l2(1,:,:,:,:)
,如果这个函数是好的随机函数。可能是我做错了什么
如何解决这个问题
请求提供的其他信息:
real(real64) function find_variance(l)
implicit none
real(real64), dimension(z_size, y_size, x_size), intent(in) :: l
integer :: z, y, x
real(real64) :: l_avg = 0
real(real64) :: sum_val = 0
do z = 1, z_size
do y = 1, y_size
do x = 1, x_size
l_avg = l_avg + l(z, y, x)
end do
end do
end do
l_avg = l_avg/(z_size*y_size*x_size)
do z = 1, z_size
do y = 1, y_size
do x = 1, x_size
sum_val = sum_val + (l(z , y, x) - l_avg)**2
end do
end do
end do
find_variance = sum_val/(z_size*y_size*x_size)
return
end function find_variance
在现代Fortran语言中,变量的初始化,如
real(real64) :: sum_val = 0
表示sum\u val
是一个具有SAVE
属性的变量(类似于C中的static
),在程序启动时仅初始化一次。相当于
real(real64), save :: sum_val = 0
SAVE
ed变量的值在整个运行期间保持不变,不会再次初始化为0。要解决此问题,只需更换
real(real64) :: sum_val !! this is a usual local variable
sum_val = 0 !! or sum_val = real( 0, real64 )
那我想应该没问题。有关更多详细信息,请参阅。
在我看来,这是Fortran的一个非常令人困惑的特性…@roygvib求和
(l(z,y,x)-l_avg)**2
除以N
(在这种情况下N
是x_size*y_size*z_size
)编辑:在你的问题中,用完整的代码来计算方差_l1_t1,方差_l1_t2等应该非常有用,因为如果他们有一些问题,这与随机数是不同的。你的0.1是默认(单一)实数。将real64
与D0
和DATAN
相结合是很奇怪的,但不应立即导致问题。顺便说一句,如果您使用Fortran 2008中的功能,我不会使用标记Fortran 90。我一直认为Fortran初始化的这种语法确实有问题…任何解决方案,请使用,我只需要一个正确的输出。你可以复制上面的代码,并尝试检查差异。上帝。。。我以前就知道这件事,但这是我的疏忽。非常感谢您@royvibsum_val
不是一个自动对象,只是一个普通的本地对象。@francescalus我检查了这个页面,它还说调用sum_val
automatic..(因为F77默认为静态)。我相应地改变了这个词。谢谢:)