Cell array or 3d array that enable its sub-matrix (2d array) freely renew themself without size constraint

Hi community,
What I am looking for is described in the title (as the row numbers of my 2d sub-matrixs are changing within a for loop).

The only expression of cell array I found, as below, doesn’t work any more.
A = Array(Array{Float64,2},3)

And this one don’t allow its sub-matrix to have different size with the initial definition e.g. (2,2).
A = [zeros(2,2) for i=1:3]

#Not also uninitialized array

A = Array{Float64,2}(undef, 2, 3, 5)
A[:, :, 5]=rand(3,3) #error as row and column has to match the original

I checked available manual about multidimensional arrays and posts as much as possible but still stay in darkness. Do anyone have a better suggestion?

Maybe this can help:

A = Array{Array{Float64,2},3}(undef,10,10,10)

Thanks I tried but still:

julia> A = Array{Array{Float64,2},3}(undef,3,3,3)
julia> A[:,:,3]=rand(4,3)
ERROR: DimensionMismatch("tried to assign 4×3 array to 3×3×1 destination")

Do you want a 3D array with 2D array elements (= 5D data)?

julia> A = Array{Array{Float64,2},3}(undef,3,3,3)
3×3×3 Array{Array{Float64,2},3}:
[:, :, 1] =
 #undef  #undef  #undef
 #undef  #undef  #undef
 #undef  #undef  #undef

[:, :, 2] =
 #undef  #undef  #undef
 #undef  #undef  #undef
 #undef  #undef  #undef

[:, :, 3] =
 #undef  #undef  #undef
 #undef  #undef  #undef
 #undef  #undef  #undef

julia> A[1,1,1]=rand(4,3)
4×3 Array{Float64,2}:
 0.573546  0.32481    0.890951
 0.7106    0.557957   0.107592
 0.471512  0.439862   0.580529
 0.743509  0.0780317  0.95439

julia> A
3×3×3 Array{Array{Float64,2},3}:
[:, :, 1] =
    [0.573546 0.32481 0.890951; 0.7106 0.557957 0.107592; 0.471512 0.439862 0.580529; 0.743509 0.0780317 0.95439]  …  #undef  #undef
 #undef                                                                                                               #undef  #undef
 #undef                                                                                                               #undef  #undef

[:, :, 2] =
 #undef  #undef  #undef
 #undef  #undef  #undef
 #undef  #undef  #undef

[:, :, 3] =
 #undef  #undef  #undef
 #undef  #undef  #undef
 #undef  #undef  #undef

For 3D data you could use a 1D array with 2d elements :

julia> B = Array{Float32,2}[]
0-element Array{Array{Float32,2},1}

julia> push!(B,rand(2,2))
1-element Array{Array{Float32,2},1}:
 [0.9932752 0.4904164; 0.2926822 0.00089553307]

julia> push!(B,rand(3,3))
2-element Array{Array{Float32,2},1}:
 [0.9932752 0.4904164; 0.2926822 0.00089553307]
 [0.44206983 0.33984074 0.8440299; 0.4682441 0.65651804 0.30746987; 0.6282512 0.76050675 0.48171687]

julia> B[1]
2×2 Array{Float32,2}:
 0.993275  0.490416
 0.292682  0.000895533
1 Like

I want a 1d array containing 2d arrays. It works. Your instruction makes my day!

A = Array{Array{Float64,2},1}(undef,10)
A[1]=rand(4,3)
A[2]=rand(7,6)
1 Like

Indexing 1d(outer)^2d(inside) by a[i] and 3d^2d by a[1,1,1] as you mentioned, while a[1,1] for 2d^2d is an exception. Could you please help me :blush:?

The array type syntax is Array{eltype,dimensionality}. The eltype of your 2x2 container array is Array{Float64,1}, which is a 1D array. Try

Array{Array{Float64,2},2}(undef,2,2)

A side-note: instead of a screenshot, could you please paste the terminal output as text between triple backticks (```) in the future? It makes it easier for others to help you.

1 Like

It seems that indexing the element of 2x2 container array could be problematic regardless of the dimension of contained array.

julia> a=Array{Array{Float64,2},2}(undef,2,2)
2×2 Array{Array{Float64,2},2}:
 #undef  #undef
 #undef  #undef

julia> a[1,1]
ERROR: UndefRefError: access to undefined reference
Stacktrace:
 [1] getindex(::Array{Array{Float64,2},2}, ::Int64, ::Int64) at .\array.jl:729
 [2] top-level scope at none:0

julia> a=Array{Array{Float64,1},2}(undef,2,2)
2×2 Array{Array{Float64,1},2}:
 #undef  #undef
 #undef  #undef

julia> a[1,1]
ERROR: UndefRefError: access to undefined reference
Stacktrace:
 [1] getindex(::Array{Array{Float64,1},2}, ::Int64, ::Int64) at .\array.jl:729
 [2] top-level scope at none:0

What would you like a[1,1] to return here? Perhaps it’s simplest to figure out what’s going on without any undef stuff:

julia> [fill(i+10j, 2,3) for i=1:2, j=1:3]
2×3 Array{Array{Int64,2},2}:
 [11 11 11; 11 11 11]  [21 21 21; 21 21 21]  [31 31 31; 31 31 31]
 [12 12 12; 12 12 12]  [22 22 22; 22 22 22]  [32 32 32; 32 32 32]

julia> a[2,3]
2×3 Array{Int64,2}:
 32  32  32
 32  32  32

julia> a[2,3][1,1]
32

Arrays store numbers densly in memory, so an array of undef just contains whatever junk happened to be in memory, interpreted as numbers, and you can index it just fine.

But an Array of Arrays stores a list of pointers, and if this is undef, there is no object to return when you index.

julia> Vector{Float64}(undef, 3)
3-element Array{Float64,1}:
 2.335323258e-314 
 2.245962545e-314 
 2.3353232737e-314

julia> ans[1]
2.335323258e-314

julia> [Vector{Int}(undef, 3) for _=1:3]
3-element Array{Array{Int64,1},1}:
 [4944151024, 4551525968, 4975935952]
 [0, 4294967296, 0]                  
 [4610370144, 4476805312, 4547078800]

julia> ans[1]
3-element Array{Int64,1}:
 4944151024
 4551525968
 4975935952

julia> v = Vector{Vector{Int}}(undef, 3)
3-element Array{Array{Int64,1},1}:
 #undef
 #undef
 #undef

julia> ans[1]
ERROR: UndefRefError: access to undefined reference

julia> v[2] = [2,3,4,5,6,7,8];

julia> v
3-element Array{Array{Int64,1},1}:
 #undef                  
    [2, 3, 4, 5, 6, 7, 8]
 #undef                  

julia> v[3] = rand(3,3)
ERROR: MethodError: no method matching Array{Int64,1}(::Array{Float64,2})

Got it. Thank you~