I want to have an in-place function that takes a vector as an argument and applies another in-place function to a subarray (in general sense).
How do I do this?
function f!(du, u)
println("\nf called")
@show u
du .= reverse(u)
return nothing
end
"""
Applies f!() to the first 2 elements.
"""
function g!(du, u)
f!(du[1:2], u[1:2])
du[3] = 17
return nothing
end
du = zeros(2)
u = [3, 11]
dug = zeros(3)
ug = [u; 0]
@show f!(du, u)
@show du
@show g!(dug, ug)
@show dug
gives
f called
u = [3, 11]
f!(du, u) = nothing
du = [11.0, 3.0]
f called
u = [3, 11]
g!(dug, ug) = nothing
dug = [0.0, 0.0, 17.0] # why not [11, 3, 17]?
In julia du[1:2] gives a copy of the slice, not a view (unfortunately). You can use the @view or @views macros, or the view function directly to construct views.
So your g! function should be
function g!(du, u)
@views f(du[1:2], u[1:2])
du[3] = 17
return nothing
end
I’m afraid I don’t get it completely.
I’m okay with the fact it’s some “special syntax”. But why does it work in REPL and not in a function (where it requires @view}? Where else will it not work?
Incidentally, I believe reverse(u) will allocate a intermediare temporary vector. A lazy non-allocated version can be had by using Iterators.reverse or reverse the indices of a view, ie
Sure, but since the question concerns in-place operations and allocations, and since I expect almost everything in an MWE to be relevant, I assumed this was too.