我在这篇文章中提到过: " Julia中是否有本地保存的数据(如Fortran' s)?" 我试图将整个fortran77代码重写为Julia。这段代码超过2000行,所以我不能把它放在这里,但我会总结一下我的问题的核心。
在这个旧程序中,广泛使用了NUERICAL RECIPIES的功能。特别是,ran1.f和ran3.f(都是随机生成器函数)。两个函数中的声明行如下:
FUNCTION ran1(idum)
INTEGER idum,IA,IM,IQ,IR,NTAB,NDIV
REAL ran1,AM,EPS,RNMX
PARAMETER (IA=16807,IM=2147483647,AM=1./IM,IQ=127773,IR=2836,
*NTAB=32,NDIV=1+(IM-1)/NTAB,EPS=1.2e-7,RNMX=1.-EPS)
INTEGER j,k,iv(NTAB),iy
SAVE iv,iy
DATA iv /NTAB*0/, iy /0/
和
FUNCTION ran3(idum)
INTEGER idum
INTEGER MBIG,MSEED,MZ
C REAL MBIG,MSEED,MZ
REAL ran3,FAC
PARAMETER (MBIG=1000000000,MSEED=161803398,MZ=0,FAC=1./MBIG)
C PARAMETER (MBIG=4000000.,MSEED=1618033.,MZ=0.,FAC=1./MBIG)
INTEGER i,iff,ii,inext,inextp,k
INTEGER mj,mk,ma(55)
C REAL mj,mk,ma(55) Knuth.
SAVE iff,inext,inextp,ma
DATA iff /0/
在上面提到的这篇文章中,我了解了朱莉娅的可变结构,显然""让我模拟SAVE和DATA语句中变量的预期行为。下面,我的可变结构
mutable struct ran1_init # or simply "type" in older versions
NTAB :: Int64
idum :: Int64
iv :: Array{Int64,1}
iy :: Int64
# constructors if necessary
end
# Initialize mutable structure for ran1
ran1_in = ran1_init(32,ISEED,zeros(Int64,32),0)
mutable struct ran3_init # or simply "type" in older versions
idum :: Int64
iff :: Int64
inext :: Int64
inextp :: Int64
ma :: Array{Int64,1}
# constructors if necessary
end
# Initialize mutable structure for ran3
ran3_in = ran3_init(ISEED,0,0,0,zeros(Int64,55))
fortran CODE使用ran1直到某一点,开始实现ran3(我想这个程序是多年来组装的,并且在某些时候,ran3被实现为生成随机数,而不是ran1)。程序中第一次使用ran3是在这个操作中:
do while (iii.le.N_emean)
t0=XA(1,1)+dble(ran3(ISEED))*(XB(1,1)-XA(1,1))
d=XA(1,2)+dble(ran3(ISEED))*(XB(1,2)-XA(1,2))
z0=XA(1,3)+dble(ran3(ISEED))*(XB(1,3)-XA(1,3))
v=XA(1,4)+dble(ran3(ISEED))*(XB(1,4)-XA(1,4))
iflag=0
stop
(为了表明此事而停止)
朱莉娅:
while (iii <= N_emean)
for i = 1:4
randomnumber = ran3(ran3_in)
XX[i] = XA[1,i] + randomnumber*(XB[1,i]-XA[1,i]);
end
t0, d, z0, v = XX;
stop
起初,我认为它工作正常。但后来我在Julia和FORTRAN CODE中看到了以下输出......实验如下:
朱莉娅
println("initial parameters")
println()
println("ISEED = ",ran3_in.idum)
println("iff = ",ran3_in.iff)
println("inext = ",ran3_in.inext)
println("inextp = ",ran3_in.inextp)
while (iii <= N_emean)
for i = 1:4
println()
println("OUTSIDE: just before entering ran3")
println("ISEED = ",ran3_in.idum)
println("iff = ",ran3_in.iff)
println("inext = ",ran3_in.inext)
println("inextp = ",ran3_in.inextp)
println()
randomnumber = ran3(ran3_in)
XX[i] = XA[1,i] + randomnumber*(XB[1,i]-XA[1,i]);
println("OUTSIDE: just exiting ran3")
println("ISEED = ",ran3_in.idum)
println("iff = ",ran3_in.iff)
println("inext = ",ran3_in.inext)
println("inextp = ",ran3_in.inextp)
println("random number : ", randomnumber)
error("JUST PLAYING AROUND")
在Fortran:
write(*,*)"initial parameters"
write(*,*)
write(*,*)"ISEED = ",ISEED
write(*,*)"iff = ",iff
write(*,*)"inext = ",inext
write(*,*)"inextp = ",inextp
do while (iii.le.N_emean)
write(*,*)
write(*,*)"OUTSIDE: just before entering ran3"
write(*,*)"ISEED = ",ISEED
write(*,*)"iff = ",iff
write(*,*)"inext = ",inext
write(*,*)"inextp = ",inextp
write(*,*)
a1ran = dble(ran3(ISEED))
write(*,*)"OUTSIDE: just exiting ran3"
write(*,*)"ISEED = ",ISEED
write(*,*)"iff = ",iff
write(*,*)"inext = ",inext
write(*,*)"inextp = ",inextp
write(*,*)"random number : ",a1ran
stop
获得: 在Julia代码中
initial parameters
ISEED = 557527639
iff = 0
inext = 0
inextp = 0
OUTSIDE: just before entering ran3
ISEED = 557527639
iff = 0
inext = 0
inextp = 0
INSIDE ran3: just entering ran3
ISEED = 557527639
iff = 0
inext = 0
inextp = 0
INSIDE ran3: just exiting ran3
ISEED = 1
iff = 1
inext = 1
inextp = 32
OUTSIDE: just exiting ran3
ISEED = 1
iff = 1
inext = 1
inextp = 32
random number : 0.253305072
在fortran代码中
initial parameters
ISEED = 557527639
iff = 0
inext = 0
inextp = 0
OUTSIDE: just before entering ran3
ISEED = 557527639
iff = 0
inext = 0
inextp = 0
INSIDE ran3: just entering ran3
ISEED = 557527639
iff = 0
inext = 0
inextp = 0
INSIDE ran3: just exiting ran3
ISEED = 1
iff = 1
inext = 1
inextp = 32
OUTSIDE: just exiting ran3
ISEED = 1
iff = 0
inext = 0
inextp = 0
random number : 0.25330507755279541
似乎SAVEed和DATAed BLOCKED变量没有在Fortran中以正确的值退出,而它们在Julia中, 1)发生了什么事? 2)在具有相同命名的DATA和SAVE块的情况下,ran1和ran3之间是否存在问题。 3)不应该是Julia输出预期或更正的输出吗?
我真的需要帮助理解这一点......谢谢
答案 0 :(得分:2)
Fortran save
属性适用于局部变量。因此,它们在功能之外是不可见的。我没有完整的Fortran代码,但对我来说,&#34;外部变量&#34;在Fortran代码中,只是不同的变量,恰好与局部变量具有相同的名称。我建议在Fortran中使用隐式无。
让#34;保存&#34; julia中的变量(或者在C中调用的静态变量),我更喜欢以下方法:
let
my_saved_variable = 0 # the value corresponds to the Fortran DATA statement
global function do_something(inc)
my_saved_variable += inc
return my_saved_variable
end
end
参数inc
被添加到已保存的变量中:
您将获得以下输出:
julia> do_something(2)
2
julia> do_something(5)
7
julia> do_something(10)
17
答案 1 :(得分:2)
这里我解决围绕Fortran代码的误解。我不想尝试详细说明朱莉娅计划的含义 - 我会将其留给其他答案,例如this one。
Fortran的重要性是范围。我对此的评论与implicit
statement密切相关。
考虑两个程序:
subroutine x
integer i
end subroutine x
subroutine y
integer i
end subroutine y
这里有两个范围,每个范围都有一个变量i
。这是两个完全不同的变量。它们之间没有任何重叠。
现在,data
语句和save
语句都没有改变。 save
语句,例如
subroutine x
integer i
save i
end subroutine
表示该变量具有save
属性。这意味着当子例程完成执行时,变量会保留其值(如果没有,变量将变为未定义)。
data
语句,例如
subroutine y
integer i
data i/4/
end subroutine y
使用特定值显式初始化变量。首次输入子例程y
时,变量i
的值为4
。至关重要的是,data
语句还为初始化变量提供了save
属性。因此,如果y
&#39; s i
的值已从4
更改,则新值将在下次进入子例程时保留。
在此上下文中,所有内容都包含data
和save
语句。没有影响范围。