I am learning broadcasting in julia. I would like to adapt one vector in-place by multiplying it with the contents of another vector, without creating a copy. I tried this:
function mymultiply!(a,b)
a*=b
return ;
end
a=[1,2,3,4]
b=[10,100,1000,10000]
mymultiply!.(a,b)
a
But this does not adapt a. Is this not passing through a pointer and is a new allocation made? How do I avoid this and keep it in-place?
Oh yes thanks that works indeed! I tried adapting my function like this:
function mymultiply!(a,b)
a.*=b
return ;
end
Which resulted in the error.
The suggestion a.* =b does work for something simple like multiplication, but if I want to do something more complicated for which I’d like to write my own function, could I adapt mymultiply to obtain the same behavior as a.* =b?
julia> a=[1,2,3,4]; b=[10,100,1000,10000];
julia> function mymultiply!(a,b)
a.*=b
return ;
end
mymultiply! (generic function with 1 method)
julia> mymultiply!(a,b)
julia> a
4-element Vector{Int64}:
10
200
3000
40000
I think what’s confusing you may be that you are also trying to call mymultiply!.(a,b) with a dot. To use broadcasting, you generally want to do one but not both of:
Write a function f(x,y) that takes arrays as arguments. Insidef(x,y), use as many broadcast operations as you want. You can even modify x or y in-place if you want (in which case it is conventional to name f! with a !).
Write a function f(x,y) that takes scalarsas arguments. Call it on arrays withf.(a,b), and assign the results in-place with (for example) a .= f.(a,b)`.
Do one or the other! For example, the 2nd strategy in this case would be:
function mymultiply(a,b)
return a * b
end
a .= mymultiply.(a,b) # apply to arrays a,b, assigning result in-place to a
(You can’t do a .*= b in a function that takes scalars as arguments, because scalars are immutable. And a += b is equivalent to a = a + b which does not mutate the argument a.)