Suppose I have an (immutable) struct that holds many large arrays. Not all of these arrays need to exist, however, it just depends on the user-specified problem setup. So I defined my struct like this:
@with_kw struct mystruct
a::Union{Nothing,Matrix{Float64}} = nothing
b::Union{Nothing,Matrix{Float64}} = nothing
c::Union{Nothing,Matrix{Float64}} = nothing
d::Union{Nothing,Matrix{Float64}} = nothing
end
Now I have some methods that initialize this struct differently depending on what the user specifies:
function init_my_struct(::Val{1})
return mystruct(a=zeros(500,500),b=zeros(500,500))
end
function init_my_struct(::Val{2})
return mystruct(c=zeros(500,500),d=zeros(500,500))
end
function init_my_struct(::Val{3})
return mystruct(a=zeros(500,500),b=zeros(500,500),c=zeros(500,500),d=zeros(500,500)),
end
(I’m dispatching by value just to highlight the three different cases).
If you notice, the third case is really just a combination of the first two cases. In this particular example, it is easy to manually rewrite out each case. But in my actual code, I have many cases for dozens of arrays…
Is there an efficient way to pass blocks of parameters like this? Maybe via metaprogramming?
I thought about writing another function (one for each case) which simply returns a vector of all the arrays for that particular case, then I could splat them as needed. However, this seems extremely inefficient as that would effectively allocate each array twice…
I appreciate the help!