Copying cross-referenced values

Hi,
I have a rather newbie question. If I enter this code:

vecvec = [[5]]
doubled = [vecvec;vecvec]
copied = deepcopy(doubled)
println( "doubled:  ", doubled)
println( "copied:  ", copied)
copied[1][1] = 7
println( "doubled after change:  ", doubled)
println( "copied after change:  ", copied)

then I get this output:

doubled:  [[5], [5]]
copied:  [[5], [5]] 
doubled after change:  [[5], [5]]
copied after change:  [[7], [7]]

I think I get why the second element of copied is altered, but I’m not sure why this doesn’t happen if vecvec is changed to vec = [5] and the second index removed in line 6. I also don’t know how to replace line 3 by a copy that is so deep that it ignores the duplication of references in line two and so yields copied after change: [[7],[5]]. Can anyone help?

And before anyone aks: I need to have a Vector of Vectors because in my application it is a population of chromosomes, each of which is itself a vector.

Thanks and best wishes,
Niall.

When you write [vec;vec] you are defining: “a vector that contains vec in its first element, and vec in its second element”. There is no hard binding between the first and second element of that vector; it just happened that you assigned the same object to both; but later on you can replace one element without changing the other. That’s what happens if you do:

vec = [5]
doubled = [vec;vec]
copied = deepcopy(doubled)
copied[1] = 7

(In the last line there you are telling: “replace the first element of copied by 7”.)

On the other hand, with copied[1][1] = 7 in your actual example, you are not replacing the object referred to by copied[1], but mutating it (actually, replacing its first index), so other references to the same object (as happens with copied[2] in this case) will reflect the same mutation.

Broadcasting:

copied = deepcopy.(doubled)

Oh, brilliant - thanks very much! :smiley: I thought deepcopy was already doing the broadcasting.

What deepcopy ensures that the contents of the output are wholly independent from those of the input, but the structure is the same, so if the input contains multiple references to a single object, the output will also have that.

By the way, perhaps you would like to have independent copies of [5], not only in copied, but also in doubled. If so, an alternative would be:

vec = [5]
doubled = [copy(vec) for _ = 1:2]
copied = deepcopy(doubled)
# ...

Hm. Thanks very much for the tip, but I think in my case it would raise my overhead. Before recombining parent chromosomes, I build up a careful system of references to parents that are selected for mating. These references can appear multiply, and are shuffled around in various ways, so I think it’s more efficient in my case to do the shuffling around using references, and only cash them out as independent objects right at the very end (using your broadcast deepcopy).