朱莉娅是否有本地保存的数据(如Fortran's)?

时间:2018-02-18 18:35:04

标签: fortran julia

我目前正在尝试将整个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中被取代以便完成相同的行为?

1 个答案:

答案 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”就像一个“状态”变量,因此我们可以将其替换为类型变量:)