Julia中是否存在本地保存的数据(如Fortran's)? [英] Is there locally saved data (like Fortran's) in Julia?

查看:174
本文介绍了Julia中是否存在本地保存的数据(如Fortran's)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将整个Fortran 77代码重新写入Julia。在这个Fortran代码中,有各种局部变量和 SAVE 属性(来自 SAVE 语句或者在一个 DATA 语句)。

问题是:我没有能够重现与将在Fortran中预期这些保存的变量。例如,代码中有许多随机生成器程序从数字Recipies中提取。特别是, ran3.f ,不仅从主程序中调用,而且从其中的许多不同的子例程中调用。


$ b $ < ran3.f 表示:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆