Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filling the array with array does not work as I expected

Tags:

arrays

julia

I want to make a multiple array whose entry is multiple array, and want to push some array one by one into the entry.

For example, I made 2 x 3 Matrix named arr and tried to fill [1,1] and [1,2] entries with 4 x 4 Matrix spawned by randn(4,4).

arr = fill(Matrix{Float64}[], 2, 3)
push!(arr[1,1],randn(4,4))
push!(arr[1,2],randn(4,4))
println(arr[1,1])
println(arr[1,2])
println(arr[1,3])

However, the result is all the entries of arr (other than [1,1] and [1,2]) were filled with the same randn(4,4), instead of just [1,1] and [1,2] filled with randn(4,4):

[[-0.15122805007483328 0.6132236453930502 -0.9090110366765862 1.2589924202099898; -1.120611384326006 -0.9083935218058066 0.7252290006516056 1.0970416725786256; -0.19173238706933265 1.3610525411901113 -0.05258697093572793 0.7776085390912448; 0.18491459001855373 -2.0537142669734934 0.3482557186126859 0.0047622478008474845], [0.23422967703060255 -0.51986351753462 0.45947166573674303 0.31316899298864387; 0.3704450103622709 -0.8186574197233013 -0.9990329964554037 -0.8345957519924763; 0.56641529964098 -0.8393435538481216 -0.6379336546939682 1.1843452368116358; 0.9435767553275002 0.0033471181565433127 -1.191611491619908 1.3970554854927264]]
[[-0.15122805007483328 0.6132236453930502 -0.9090110366765862 1.2589924202099898; -1.120611384326006 -0.9083935218058066 0.7252290006516056 1.0970416725786256; -0.19173238706933265 1.3610525411901113 -0.05258697093572793 0.7776085390912448; 0.18491459001855373 -2.0537142669734934 0.3482557186126859 0.0047622478008474845], [0.23422967703060255 -0.51986351753462 0.45947166573674303 0.31316899298864387; 0.3704450103622709 -0.8186574197233013 -0.9990329964554037 -0.8345957519924763; 0.56641529964098 -0.8393435538481216 -0.6379336546939682 1.1843452368116358; 0.9435767553275002 0.0033471181565433127 -1.191611491619908 1.3970554854927264]]
[[-0.15122805007483328 0.6132236453930502 -0.9090110366765862 1.2589924202099898; -1.120611384326006 -0.9083935218058066 0.7252290006516056 1.0970416725786256; -0.19173238706933265 1.3610525411901113 -0.05258697093572793 0.7776085390912448; 0.18491459001855373 -2.0537142669734934 0.3482557186126859 0.0047622478008474845], [0.23422967703060255 -0.51986351753462 0.45947166573674303 0.31316899298864387; 0.3704450103622709 -0.8186574197233013 -0.9990329964554037 -0.8345957519924763; 0.56641529964098 -0.8393435538481216 -0.6379336546939682 1.1843452368116358; 0.9435767553275002 0.0033471181565433127 -1.191611491619908 1.3970554854927264]]

What is wrong? Any information would be appreciated.

like image 780
ten Avatar asked Dec 23 '22 15:12

ten


2 Answers

When you do arr = fill(Matrix{Float64}[], 2, 3) all 6 elements point into exactly the same location in memory because fill does not make deep copy - it just copies the references. Basically, using fill when the first argument is mutable usually turns out not to be a good idea.

Hence what you actually want is:

arr = [Matrix{Float64}[] for i in 1:2, j in 1:3]

Now each of 6 slots will have its own address in the memory.

like image 98
Przemyslaw Szufel Avatar answered Jan 30 '23 02:01

Przemyslaw Szufel


This way of creating the array implies that each element will be Float64, i.e. a scalar. You need to fix the type signature. So for instance you could do

D = Matrix{Array{Float64, 2}}(undef, 2, 3)

if you want it to have 2-dimensional arrays as elements (the Float64,2 does that)

and then allocate

D[1,1] = rand(4,4)
D[1,2] = rand(4,4)

to give you (or rather, me!):

julia> D[1,1]
4×4 Matrix{Float64}:
 0.210019  0.528594  0.0566622  0.0547953
 0.729212  0.40829   0.816365   0.804139
 0.39524   0.940286  0.976152   0.128008
 0.886597  0.379621  0.153302   0.798803

julia> D[1,2]
4×4 Matrix{Float64}:
 0.640809   0.821668  0.627057  0.382058
 0.532567   0.262311  0.916391  0.200024
 0.0599815  0.17594   0.698521  0.517822
 0.965279   0.804067  0.39408   0.105774
like image 41
Jarle Avatar answered Jan 30 '23 04:01

Jarle