Assignments, Copies and Deepcop

This is a question regarding the use of “=” signs in Julia.

I can do the following for-loop in MATLAB

for ii = 1 : dt
    ηp1 = shallowwave1D(ηn,ηm1,r);
    ηm1 = ηn; ηn = ηp1; 
end

Can the same be done in Julia? Or will there be some issues with copies where whatever I do to ηn changes ηm1 (see the second statement in the second line of the for-loop)?

Just asking, because this has tripped me up multiple times in Python where I needed to do copying to resolve the issue.

Do I need to do

for ii = 1 : dt
    ηp1 = shallowwave1D(ηn,ηm1,r);
    ηm1 = deepcopy(ηn); ηn = deepcopy(ηp1); 
end

such that they are all independent of each other?

for ii = 1 : dt
    ηp1 = shallowwave1D(ηn,ηm1,r);
    ηm1 = ηn; ηn = ηp1; 
end

I am really confused about this loop. Why is the looping variable ii not used inside the loop itself?

for ii = 1 : dt
    ηp1 = shallowwave1D(ηn,ηm1,r);
    ηm1 = deepcopy(ηn); ηn = deepcopy(ηp1); 
end

It would really help if you can tell us what is

  1. ηp1
  2. ηn

Is it a scalar (ie Float64), a struct , an array , a Dict or a set?

They are all supposed to be numeric arrays (i.e. something like [1,2,3,4]).

1 Like

If they are arrays of arrays then use deepcopy to be really safe

if they are just arrays of scalars (ie array of Float64), you can use copy

1 Like

Noted! Thanks!
If I didn’t use copy or deepcopy, what would happen?

Noted! Thanks!
If I didn’t use copy or deepcopy, what would happen?

Then you get aliasing

julia> a = [1 2 3]
1×3 Array{Int64,2}:
1 2 3

julia> b = a
1×3 Array{Int64,2}:
1 2 3

julia> b[2]=666
666

julia> b
1×3 Array{Int64,2}:
1 666 3

julia> a
1×3 Array{Int64,2}:
1 666 3

May also be helpful to see this behavior

julia> a = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> b = a[:]
3-element Array{Int64,1}:
 1
 2
 3

julia> b[1]
1

julia> b[1] = 4
4

julia> b
3-element Array{Int64,1}:
 4
 2
 3

julia> a
3-element Array{Int64,1}:
 1
 2
 3

In the above example, a does not change when we change b. You could also check out point #5 in

3 Likes

Thank you so much for the help!

In this specific case, you don’t need to copy.

ηn = ηp1 does not mutate ηn, but re-binds it to another array. So, ηm1 is not affected.
It would only be affected if you modified ηn in-place, e.g. with copyto!(ηn, ηp1).

2 Likes

In addition to @Vasily_Pisarev’s answer (with which I fully agree), I would like to add that I think a common idiom to perform what (I think) you want to do would be something like:

# Initialize input arrays
ηm1 = something
ηn = something

# Preallocate an array for the result
ηp1 = similar(ηn)

# No need to have a named iteration variable if you don't use it:
# naming the variable "_" makes it clear that it is not used
for _ = 1 : dt
  # shallowwave1D is rewritten in such a way that it mutates ηp1
  # instead of creating a new array (hence the "!" suffix)
  shallowwave1D!(ηp1,ηn,ηm1,r)

  # simply rotate the variables, leaving the now-unused ηm1 array 
  # free to be modified as ηp1 in the next iteration
  (ηm1, ηn, ηp1) = (ηn, ηp1, ηm1)  
end

As already explained, this way your underlying arrays are only re-bound to other variables, but remain distinct (i.e. at any point in time, there are 3 arrays, independent from one another in the sense that modifying a coefficient in one of the array will not affect other arrays)

1 Like

Mmmmmm interesting. Are there performance benefits to this, actually? Because I’m very new to the entire concept of mutable things, coming from MATLAB where all I did all day was reassign values to the variables haha.

Yes, often by orders of magnitude. The fact that Matlab insists on silently copying things all over the place is one of many design choices that make that language slow.

But don’t just take my word for it–use https://github.com/JuliaCI/BenchmarkTools.jl to test for yourself, and feel free to ask follow up questions if you get surprising results.

1 Like

For example, in this post we were able to make the original user’s code over 3000 times faster by avoiding accidental copies and memory allocation.

1 Like

ooooooooh okay thank you so much for the help I will go look at this again!