Hello there, this is sort of a follow up to the question I posted yesterday about improving memory allocation in a simulation. You can find that question here for any context.
Following the advice @DNF, I decided to implement pre-allocated arrays and return a copy of the array with the updated simulation.
Now I am adding layers of complexity. I’m really working on generating training data for a Temporal Difference algorithm using random walks, but this example shows generating a random number until we reach an even number and returning that sequence.
Now I would like to generate 2 episodes 5 times such that my training data becomes a nested array typed as Array{Array{Array{Int64}}}(undef, 5)
.
The size of 2nd array should be 2, and the inner most array is technically “unknown” in size. But I wish to limit it to 10 or less.
Here is my code example:
function gen_array!(cache)
for i in 2:length(cache)
num = rand(eltype(cache))
cache[i] = num
iseven(num) && return cache[1:i]
end
gen_array!(cache)
end
function episode!(episode, sim)
for i in 1:length(episode)
episode[i] = gen_array!(sim)
end
return episode
end
function simulate!(train, E)
START = Array{Int64}(undef, 10)
START[1] = 1333
EPISODES = Array{Array{Int64}}(undef, E)
for i in 1:length(train)
train[i] = episode!(EPISODES, START)
end
end
function main()
N::Int64 = 5
E::Int64 = 2
train = Array{Array{Array{Int64}}}(undef, N)
simulate!(train, E)
train
end
The general idea is that we preallocate train and initialize simulation. We then start to fill our episodes through gen_array!()
.
You’ll notice this is a recursive function.
My reasoning here is, say we have hit the size limit of the array and still have not generated an even number. I don’t want to grow the size of the vector, but restart the function and write over the array until we reach a sequence that generates a random number.
I thought this was working until I closely inspected the output
include("example.jl")
main (generic function with 1 method)
julia> main()
5-element Array{Array{Array{Int64,N} where N,N} where N,1}:
[[1333, 5175378229263772070], [1333, -7110769136095499899, 2890408208590898501, -2599245076049037924]]
[[1333, 5175378229263772070], [1333, -7110769136095499899, 2890408208590898501, -2599245076049037924]]
[[1333, 5175378229263772070], [1333, -7110769136095499899, 2890408208590898501, -2599245076049037924]]
[[1333, 5175378229263772070], [1333, -7110769136095499899, 2890408208590898501, -2599245076049037924]]
[[1333, 5175378229263772070], [1333, -7110769136095499899, 2890408208590898501, -2599245076049037924]]
Each sequence is different, but every episode is the same. I think this has something to do with the function being recursive. That it gets so deep in the stack that once it hits the return it passes it back to the previous function call and it disappears or something.
Any ideas?