Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Julia中的函数内本地化记忆_Julia_Memoization - Fatal编程技术网

在Julia中的函数内本地化记忆

在Julia中的函数内本地化记忆,julia,memoization,Julia,Memoization,有没有一种方法可以在函数中本地化memoization(通过Memoize.jl)?或者至少删除由备忘录创建的词典 澄清:假设我定义了一个函数f(x,y)。我想为y的每一个新值创建一个新表。也就是说,给定y=y0,f(,y0)对x,x-1等自身进行迭代,但给定一个新的y=y1,我不需要为y0存储旧表,这样就可以释放内存。我该怎么做 解决方案: cachedfib() = begin global dict = Dict() global dict2 = Dict() fu

有没有一种方法可以在函数中本地化memoization(通过Memoize.jl)?或者至少删除由备忘录创建的词典

澄清:假设我定义了一个函数f(x,y)。我想为y的每一个新值创建一个新表。也就是说,给定y=y0,f(,y0)对x,x-1等自身进行迭代,但给定一个新的y=y1,我不需要为y0存储旧表,这样就可以释放内存。我该怎么做

解决方案:

cachedfib() = begin
    global dict = Dict()
    global dict2 = Dict()
    function _fib(n::Int, a::Int)
        if !haskey(dict2, a)
            dict2[a] = true
            dict = Dict()
        end
        if haskey(dict, (n, a))
            return dict[(n, a)]
        elseif n < 2
            dict[(0, a)] = 0
            dict[(1, a)] = 1
            return dict[(n, a)]
        else
            dict[(n, a)] = a*(_fib(n - 1, a) + _fib(n - 2, a))
            return dict[(n, a)]
        end
    end
end
fib = cachedfib()

fib(10, 1)
fib(10, 2)
cachedfib()=开始
全局dict=dict()
全局dict2=Dict()
函数fib(n::Int,a::Int)
如果!haskey(dict2,a)
dict2[a]=真
dict=dict()
结束
如果haskey(dict,(n,a))
返回指令[(n,a)]
elseif n<2
dict[(0,a)]=0
dict[(1,a)]=1
返回指令[(n,a)]
其他的
dict[(n,a)]=a*(_fib(n-1,a)+_fib(n-2,a))
返回指令[(n,a)]
结束
结束
结束
fib=cachedfib()
fib(10,1)
fib(10,2)
现在调用
dict
dict2
,检查字典是否在第二个参数每次更改时都刷新。如果要存储的参数是整数,并且使用
Array
而不是
Dict

let Aold = nothing
global foo
function foo(A::AbstractArray)
    if A == Aold
        println("Same as last array")
    else
        Aold = A
    end
    nothing
end
end
结果:

julia> A = rand(2,2)
2x2 Array{Float64,2}:
 0.272936  0.153311
 0.299549  0.703668

julia> B = rand(2,2)
2x2 Array{Float64,2}:
 0.6762    0.377428
 0.493344  0.240194

julia> foo(A)

julia> foo(A)
Same as last array

julia> foo(B)

julia> foo(A)

julia> foo(A)
Same as last array

julia> Aold
ERROR: UndefVarError: Aold not defined

要使用记忆技术,可以使用
let
或闭包。请看一下我快速实现的阶乘(带闭包)


谢谢@tholy,所以我需要做的就是将函数定义包装在
let
中?我以前从未见过这种构造。我可以以某种方式使用Memoize.jl吗?在
@memoize
创建的对象保留在内存中的情况下,它似乎不起作用…这与memoize.jl无关。如果您想使用memoize.jl,最好在该存储库中打开一个问题。谢谢@maciek leks,我试着使用
let
块,就像@tholy的例子一样,但在我运行它之后,它似乎没有释放内存,请检查上面的编辑。@amrods,这是记忆技术的经验法则吗?我已经编辑了我的答案,添加了缓存的大小。因此,向缓存中添加一个新值会增加_阶乘函数的大小,其值为new_cache_size-old_cache_size。IMHO whos()将绑定变量size添加到作用域函数的作用域中。但是假设,就像我的例子一样,我定义了一个函数
f(x,y)
。我想为y的每一个新值创建一个新表。也就是说,给定y=y0,f(,y0)对x,x-1等自身进行迭代,但给定一个新的y=y1,我不需要为y0存储旧表,这样就可以释放内存。我该怎么做?我希望我能理解。因此,let块非常危险,因为每次调用代码时它都会创建一个新的作用域。这不是一个问题,但这样做是为了将变量注入函数,即for循环。因此,我建议使用闭包并测试是否出现新的y值。如果是,请通过创建缓存来重新创建缓存。i、 在我的例子中,让“t”扮演“y”的角色。我会这样做:“函数_factorial(n,t=false)if t _cache=[1]end if nwith_cached_factorial() = begin local _cache = [1] #cache factorial(0)=1 function _factorial(n) if n < length(_cache) println("pull out from the cache factorial($n)=$(_cache[n+1])") _cache[n+1] else fres = n * _factorial(n-1) push!(_cache, fres) println("put factorial($n)=$fres into the cache of the size=$(sizeof(_cache))") #a fres end end end
julia> myf = with_cached_factorial()
_factorial (generic function with 1 method)

julia> myf(3)
pull out from the cache factorial(0)=1
put factorial(1)=1 into the cache of the size=16
put factorial(2)=2 into the cache of the size=24
put factorial(3)=6 into the cache of the size=32
6

julia> myf(5)
pull out from the cache factorial(3)=6
put factorial(4)=24 into the cache of the size=40
put factorial(5)=120 into the cache of the size=48
120

julia> myf(10)
pull out from the cache factorial(5)=120
put factorial(6)=720 into the cache of the size=56
put factorial(7)=5040 into the cache of the size=64
put factorial(8)=40320 into the cache of the size=72
put factorial(9)=362880 into the cache of the size=80
put factorial(10)=3628800 into the cache of the size=88
3628800