Is there a way to initialize an array that is a subtype of AbstractArray
?
For example, x = []
initializes Vector
s, but how can I initialize an object that can be any arbitrary subtype of AbstractArray
? is it possible?
Can you give a specific example of what you want to achieve?
I don’t see an interface method here which would allow to do so.
Not sure if I fully understand the question but from the manual section on Abstract Types:
Abstract types cannot be instantiated, and serve only as nodes in the type graph, thereby describing sets of related concrete types: those concrete types which are their descendants.
this combined with
julia> isabstracttype(AbstractArray)
true
makes me think the answer to your question is no, but I might have misunderstood it.
Yes, I understand I cannot instantiate an abstract type. This is what I am trying to do:
function f(x::T) where T <: AbstractArray
t = typeof(x)
x0 = t[] # this is meant to be an empty array of type T above
# some code
return x0
end
Okay, but doesn’t the function you posted already do what you want then? A shorter version of your function is just:
julia> function f(x::T) where T <: AbstractArray
T[]
end
f (generic function with 1 method)
julia> f(rand(2))
Vector{Float64}[]
julia> f(rand(Int, 2))
Vector{Int64}[]
julia> f(5.0)
ERROR: MethodError: no method matching f(::Float64)
Closest candidates are:
f(::T) where T<:AbstractArray at REPL[43]:1
Stacktrace:
[1] top-level scope
@ REPL[46]:100:
I think T[]
creates parametric versions of regular Array
s, not other subtypes of AbstractArray
.
It seems like I’m still misunderstanding what you are trying to do. Can you show an example where the function I posted doesn’t do what you need it to do?
This may be a silly example but it illustrates what I am trying to do (and failing):
julia> using LinearAlgebra
julia> function f(x::T) where T <: AbstractArray
T[]
end
f (generic function with 1 method)
julia> x = rand(2, 2)
2Ă—2 Matrix{Float64}:
0.791934 0.93072
0.450938 0.813264
julia> xt = transpose(x)
2Ă—2 transpose(::Matrix{Float64}) with eltype Float64:
0.791934 0.450938
0.93072 0.813264
julia> xt |> typeof
Transpose{Float64, Matrix{Float64}}
julia> xt isa Transpose
true
julia> xt isa AbstractArray
true
julia> f(xt)
Transpose{Float64, Matrix{Float64}}[]
julia> f(xt) |> typeof
Vector{Transpose{Float64, Matrix{Float64}}} (alias for Array{Transpose{Float64, Array{Float64, 2}}, 1})
julia> f(xt) isa AbstractArray
true
julia> f(xt) isa Transpose
false
julia> f(xt) isa Array
true
T[]
creates regular arrays whose elements are of type T
, rather than an empty “container” of type T
. This is the same behavior that creates an array with elements that are floats from Float64[]
.
I feel like you might be asking for the array to be of the type T
, but this code is actually making a new array that contains the type T
. Which one is the intended one?
For example UnitRange
is a subtype of AbstractArray
, but I don’t think initializing one empty makes much sense so I’m not sure this is a good idea in general (in case you asked for the array to be of type T
).
EDIT:
Didn’t see you clarification until after I posted, but it seems like you meant the case I brought up. My feeling is there is no general method to create a meaningful empty collection of the type, though I’m not entirely sure.
Yes, that is what I want. I am trying to figure out a way for the ParticleSwarm
algorithm of Optim
to accept ComponentArrays
. Line 36 of this
https://github.com/JuliaNLSolvers/Optim.jl/blob/master/src/multivariate/solvers/zeroth_order/particle_swarm.jl#L36
initializes the limits with empty “regular” arrays, I was thinking whether there was a way to generalize that to be empty arrays (read containers) of any given subtype of AbstractArray
.
It is not intrinstically true that all AbstractArrays can have empty instances of them created.
but you might be after similar
?
I guess it can’t be done then
The problem with similar
is that it populates the containers.
At least you can give a dims
argument to similar
. But I understood you are interested in initializing the new array somehow arbitrarily?
So am I correct in that you have some ComponentArray
s that you want to send as the lower
and upper
parameters to ParticleSwarm
?
Depending on exactly what the goal is it could maybe be done like ParticleSwarm(; lower=collect(lower_component), upper=collect(upper_component))
. This converts the ComponentArray
s to arrays before sending them.
If you need to send ComponentArrays
for some reason I don’t think that is possible since ParticleSwarm
is specifically typed to store a vectore here:
https://github.com/JuliaNLSolvers/Optim.jl/blob/master/src/multivariate/solvers/zeroth_order/particle_swarm.jl#L2
you can pass in the dims argument to make it of length 0.