Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the connection between Refs and Broadcasting in Julia

Tags:

julia

For two objects A and B we could previously get the vector [A*A, A*B] with the code A .* [A, B]. From the deprecation warnings in Julia 0.7, it seems that the new way to do this is to use a reference of the first A. So it becomes Ref(A) .* [A,B].

It doesn't seem that there is a strong link between references and broadcasting operations. What is the link here and why is using a Reference preferred (by the deprecation warnings at least)?

Minimal Working Example

import Base.*
struct example
    num::Int
end
function *(lhs::example, rhs::example)
    return example(lhs.num * rhs.num)
end
A = example(2)
B = example(4)
# Previously this could be done as follows.
A .* [A, B]
# Now we need to use Refs
Ref(A) .* [A, B]
like image 911
Stuart Avatar asked Jan 01 '23 23:01

Stuart


1 Answers

I will here refer to the main case of Ref, that is when you pass it one argument (there are also other subtypes of Ref but they are not relevant for us here). Writing Ref(x) creates a mutable wrapper around object x. The wrapper is a very simple RefValue type defined in the following way:

mutable struct RefValue{T} <: Ref{T}
    x::T
    RefValue{T}() where {T} = new()
    RefValue{T}(x) where {T} = new(x)
end

Now why it is useful, because Ref has defined the following utility functions:

eltype(x::Type{<:Ref{T}}) where {T} = @isdefined(T) ? T : Any
size(x::Ref) = ()
axes(x::Ref) = ()
length(x::Ref) = 1
ndims(x::Ref) = 0
ndims(::Type{<:Ref}) = 0
iterate(r::Ref) = (r[], nothing)
iterate(r::Ref, s) = nothing
IteratorSize(::Type{<:Ref}) = HasShape{0}()

which means that it can be used in broadcasting as only objects that have axes defined and support indexing can be used with broadcast.

Fortunately it is easy to avoid writing Ref(A) all the time.

Just define:

Base.broadcastable(e::example) = Ref(e)

and the machinery of broadcast will work again as Base.broadcastable is called on each argument of broadcast.

More details about customizing broadcasting can be found here https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting.

like image 99
Bogumił Kamiński Avatar answered Mar 16 '23 02:03

Bogumił Kamiński