我目前正在尝试将整个Fortran 77代码重写为Julia。在此Fortran代码中,存在具有SAVE
属性的各种局部变量(来自SAVE
语句或在DATA
语句中显式初始化时)。
问题是:我无法重现与Fortran中这些已保存变量相同的结果。例如,代码中有许多从Numerical Recipies中提取的随机生成器程序。特别是ran3.f
,不仅来自主程序内部,而且来自其中的许多不同子程序。
ran3.f
州:
FUNCTION ran3(idum)
c Returns a uniform random deviate between 0.0 and 1.0.
c Set idum to any negative value to initialize or reinitialize the sequence.
INTEGER idum
INTEGER MBIG,MSEED,MZ
REAL ran3,FAC
PARAMETER (MBIG=1000000000,MSEED=161803398,MZ=0,FAC=1./MBIG)
INTEGER i,iff,ii,inext,inextp,k
INTEGER mj,mk,ma(55)
SAVE iff,inext,inextp,ma
DATA iff /0/
if(idum.lt.0.or.iff.eq.0)then
CODE ... Etc, etc...
return
end
我能够在给定特定种子的情况下重现相同的结果(随机数),并且还能根据预期在整个程序和子程序中运行,但它只是通过使用大量返回变量和输入变量。
两行如何
SAVE iff,inext,inextp,ma
DATA iff /0/
在Julia中被取代以便完成相同的行为?
答案 0 :(得分:1)
为了尽可能地使用SAVEed数据或COMMON块转换代码,我们可以使用一个常量的,全局的,可变的struct变量(放在顶级范围内),例如
mutable struct myfunc_common_t # or simply "type" in older versions
num :: Int
# constructors if necessary
end
const myfunc_common = myfunc_common_t( 0 )
function myfunc( idum )
com = myfunc_common
if idum < 0
com.num = 100
else
com.num += 1
end
@show com.num
end
function myshow()
@show myfunc_common.num
end
myfunc( -1 )
myfunc( 123 )
myfunc( 456 )
myfunc( 789 )
myshow()
给出了
com.num = 100
com.num = 101
com.num = 102
com.num = 103
myfunc_common.num = 103
这种常量全局变量的使用是类型稳定的(从@code_warntype可以看出)但它可能不适合并行计算(所以要小心......)。如果可能的话,我认为将一些类型变量显式传递给函数会很好(并在函数中改变它,或者从函数中返回一个新的类型变量)。实际上,“idum”就像一个“状态”变量,因此我们可以将其替换为类型变量:)