Initialization of array of arrays with `fill(ones(1),2,2)`: only one vector is created

Disclaimer: this is explicit in the help entry of fill, so I am not complaining of anything…

julia> m = fill(ones(1),2,2)
2×2 Array{Array{Float64,1},2}:
 [1.0]  [1.0]
 [1.0]  [1.0]

julia> m[1,1][1] = 2
2

julia> m
2×2 Array{Array{Float64,1},2}:
 [2.0]  [2.0]
 [2.0]  [2.0]

Clearly ones(1) was called only once and the vectors at all positions are the same.

Using fill(copy(ones(1)),2,2) (this was more strange to me) also results in the same thing.

Is there, therefore, a simple syntax to use fill to create an array of independent arrays?

1 Like

No you can’t. You can use a comprehension instead, sth like [ones(1) for i in 1:2, j in 1:2].

5 Likes

Not really. After calling fill, it should always be the case that m[i] === m[j] because fill fills the array with the same (identical in every meaningful way in Julia) value.

A list comprehension like:

[ones(1) for _ in i:2, _ in 1:2]

is a common way to accomplish what you’re looking for. Alternatively, you can create a new array of arrays with Matrix{Vector{Float64}}(undef, 2, 2) and then fill it in a loop. Either solution should perform very well.

7 Likes

Great, perfect. I was trying to figure out which were the alternatives.