Jeff Fessler
2019-02-06
Julia uses a convention called "pass-by-sharing" for passing arguments to functions [https://docs.julialang.org/en/latest/manual/functions/#Argument-Passing-Behavior-1]
Here is an illustration / cautionary note.
function f1(x)
x = x .+ 1
return x
end
function f2(x)
x[1] += 1
# x[:] = x[:] .+ 1
# push!(x, 5)
return x
end
a = [3,3]
b = f1(a)
@show a,b
c = [3,3]
d = f2(c)
@show c,d
;
The same thing happens with variables, even without functions
a = [3,3]
b = a
b = b .+ 1
@show a,b, b===a
c = [3,3]
d = copy(c)
d[1] += 1
@show c,d, c===d
The reason is that d = c
does not copy c
but just makes "another pointer" to the same data,
and then
d[1] = 5
is "syntatic sugar" for
setindex!(d, 1, 5)
and the !
there reminds you that d
will be modified,
but d
points to the same data as c
so c
is also modified here.
function gd!(x, g::Function, L::Number, niter::Number)
for iter=1:niter
x .+= g(x)/L # in-place update - for large-scale problems
end
end
+=
is not in place but .+=
is¶function g1(x, y)
x += y # this does not mutate input x
return x
end
function g2(x, y)
x .+= y # this does modify input x !
return x
end
a = [3,3]
u = [1,1]
b = g1(a,u)
@show a,b
c = [3,3]
d = g2(c,u)
@show c,d
;
gd!
above, in which case use !
in function name.¶