Julia中是否存在本地保存的数据(如Fortran's)? [英] Is there locally saved data (like Fortran's) in Julia?
问题描述
我正在尝试将整个Fortran 77代码重新写入Julia。在这个Fortran代码中,有各种局部变量和 SAVE
属性(来自 SAVE
语句或者在一个 DATA
语句)。
问题是:我没有能够重现与将在Fortran中预期这些保存的变量。例如,代码中有许多随机生成器程序从数字Recipies中提取。特别是, ran3.f
,不仅从主程序中调用,而且从其中的许多不同的子例程中调用。
$ b $ <
FUNCTION ran3(idum)
c返回一个统一的随机偏差,介于0.0和1.0之间。
c将idum设置为任何负值以初始化或重新初始化序列。
INTEGER idum
INTEGER MBIG,MSEED,MZ
REAL ran3,FAC
PARAMETER(MBIG = 1000000000, (55)$ b INTEGER i,iff,ii,inext,
$ b保存iff,inext,inextp,ma
DATA iff / 0 /
if(idum.lt.0.or.iff.eq.0 )然后
CODE ...等等...
返回
结束
我已经能够根据给定的种子重现相同的结果(随机数),并根据预期在整个程序和子程序中运行,但它是只使用大量的返回变量和输入变量。
这两行怎么行
SAVE iff,inext,inextp ,ma
DATA iff / 0 /
在Julia中被替换为了实现相同为了使用SAVEed数据或COMMON块尽可能地转换代码,我们可以使用常量,全局变量,可变结构变量(放置在顶层作用域中),比如
可变结构myfunc_common_t#或者简单地在旧的type版本
num :: Int
#构造函数(如果需要)
结束
const myfunc_common = myfunc_common_t(0)
函数myfunc(idum)
com = myfunc_common
if idum< 0
com.num = 100
else
com.num + = 1
end
@show com.num
end
函数myshow()
@show myfunc_common.num
结束
$ b myfunc(-1)
myfunc(123)
myfunc(456)
myfunc(789)
myshow()
/ p>
com.num = 100
com.num = 101
com.num = 102
com.num = 103
myfunc_common.num = 103
使用这种常量全局变量类型稳定(如@code_warntype所示),但它可能不适合并行计算(所以要小心......)。如果可能的话,我认为将某个类型变量明确地传递给函数是很好的(并且在函数中对它进行变异,或者从函数返回一个新的类型变量)。事实上,idum就像一个状态变量,所以我们可以将其替换为一个类型变量:)
I am currently trying to re-write an entire Fortran 77 code into Julia. Within this Fortran code, there are various local variables with the SAVE
attribute (from a SAVE
statement or when explicitly initialized in a DATA
statement).
The problem is: I haven't been able to reproduce the same outcome that one would expect with these saved variables in Fortran. For example, the code have many random generator programs extracted from the Numerical Recipies. In particular, ran3.f
, called not only from within the main program, but from many different subroutines within it.
The ran3.f
states:
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
I have been able to reproduce the same results (random numbers) given a particular seed, and also to behave across the entire program and subroutines according to what is expected, but it was only by using a lot of returning variables and input variables.
How can the two lines
SAVE iff,inext,inextp,ma
DATA iff /0/
be replaced in Julia in order to acomplish the same behavior?
To translate the code using SAVEed data or COMMON blocks as closely as possible, we can probably use a constant, global, mutable struct variable (placed in the top-level scope), e.g.
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()
which gives
com.num = 100
com.num = 101
com.num = 102
com.num = 103
myfunc_common.num = 103
The use of such constant globals are type-stable (as seen from @code_warntype) but it may be not suitable for parallel calculations (so be careful...). If possible, I think it would be nice to pass some type variable to a function explicitly (and mutate it within a function, or return a new type variable from the function). Indeed, "idum" is like a "state" variable, so we can replace it as a type variable :)
这篇关于Julia中是否存在本地保存的数据(如Fortran's)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!