FlorianEn
FlorianEn

Reputation: 128

Unexpected behaviour by push in julia

I just started out with Julia coming from python and am doing some experimenting.

I want to create a array that is a series of 5 arrays produced by a function inside a loop I assume I misunderstand how either the for loop or push function work. I've tried the append function but then you get a array of the elements in the coords array.

trj = []

for i in 1:n
    coords = run(coords, vels)
    println(coords)
    push!(trj, coords)
end

println()
println(trj)

This is the output I get:

Any[[0.0806422, 0.785333, 0.942802], [0.0510982, 0.716546, 0.620131], [0.357414, 0.448247, 0.386514]]
Any[[0.265953, 0.785003, 0.898467], [0.230179, 0.729533, 0.656178], [0.260246, 0.571314, 0.302354]]
Any[[0.451263, 0.784673, 0.854133], [0.40926, 0.74252, 0.692224], [0.163079, 0.694381, 0.218195]]
Any[[0.636573, 0.784342, 0.809798], [0.588342, 0.755507, 0.72827], [0.065912, 0.817448, 0.134035]]
Any[[0.821884, 0.784012, 0.765463], [0.767423, 0.768494, 0.764317], [0.968745, 0.940515, 0.0498756]]

Any[Any[[0.821884, 0.784012, 0.765463], [0.767423, 0.768494, 0.764317], [0.968745, 0.940515, 0.0498756]], Any[[0.821884, 0.784012, 0.765463], [0.767423, 0.768494, 0.764317], [0.968745, 0.940515, 0.0498756]], Any[[0.821884, 0.784012, 0.765463], [0.767423, 0.768494, 0.764317], [0.968745, 0.940515, 0.0498756]], Any[[0.821884, 0.784012, 0.765463], [0.767423, 0.768494, 0.764317], [0.968745, 0.940515, 0.0498756]], Any[[0.821884, 0.784012, 0.765463], [0.767423, 0.768494, 0.764317], [0.968745, 0.940515, 0.0498756]]]

As you can see the trj array is just the last version of coords times 5 instead of a series of the 5 produced coords arrays.

Upvotes: 0

Views: 160

Answers (1)

Bill
Bill

Reputation: 6086

You only have one copy of the elements in coords, and modify those elements with your run() function. This is one reason Julia has a convention that argument-mutating functions be named with a !, as run!(coords, vels), to remind you of this. I would suggest you change run() to modify a copy of its argument and return it, but if you don't want to do that you could do:

trj = Vector{Vector{Vector{Float64}}}()

for i in 1:n
    coords = run(coords, vels) # should be called run!
    println(coords)
    push!(trj, deepcopy(coords))
end

println()
println(trj)

deepcopy() gets you new elements in the vector, so the next call to coords() does not overwrite them.

Upvotes: 2

Related Questions