Is I mentioned in this post: "Is there locally saved data (like Fortran's) in Julia?" I am attempting to re-write an entire fortran77 code into Julia. This code is more than 2000 lines, so I won't be able to put it in here, but I will summarize the core of my problem.
In this old program, there are extensive use of functions from NUERICAL RECIPIES. In particular, ran1.f and ran3.f (both are random generator functions). The declaration lines in both functions are as follow:
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/
and
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/
In this mentioned post(above), I learned about the mutable structures in Julia that "apparently" let me simulate the expected behavior of the variables inside the SAVE and DATA statements. Below, my mutable structures
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))
The fortran CODE uses ran1 until some point, where started to implement ran3 (I guess the program was assembled throughout the years, and in some point ran3 was implemented to generate random numbers, instead ran1). The first time ran3 is used in the program is in this operation:
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
(Stopped for the purpose of showing this matter)
In Julia:
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
At first, I thought it was working fine. But then I saw the following outputs in both Julia and FORTRAN CODE... the experiment bellow:
In Julia
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")
In 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
Getting: In Julia code
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
In fortran code
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
Seems like the SAVEed and DATAed BLOCKED variables are not exiting with the correct values in Fortran, while they do in Julia, 1) What is going on?. 2) Is there a problem between ran1 and ran3 for having the same named DATA and SAVE blocks. 3) Shouldn't be the Julia outputs the expected or corrected output?
I really need help understanding this...thanks