What Matt is saying is that the first option is probably what you do _not_ want: all elements of the matrix z point to the same location in memory. Just try to change one of them!
On Tue, Nov 3, 2015 at 4:10 PM, Ján Dolinský <[email protected]> wrote: > Hi Matt, > > Thanks for the tips. The 1st example is quite neat and compact (similar to > sub & fill!). the for loop is obviously a good option too. > > Best Regards, > Jan > > Dňa utorok, 3. novembra 2015 15:59:37 UTC+1 Matt Bauman napísal(-a): > >> The ability to assign a single element into multiple locations like this >> is called scalar broadcasting. When you have an array of arrays, however, >> each element isn't a scalar. So it's trying to assign the elements of the >> right side (Float64s) to the elements of the right side (matrices). You >> can work around this several ways: >> >> Wrap the right had side in an array of the appropriate size. Note that, >> like using sub and fill! above, this puts exactly the same matrix (with >> shared data) in all four locations: >> >> julia> z[2:5] = fill(rand(2,2), 4); z >> 10-element Array{Array{Float64,2},1}: >> #undef >> [0.144618,0.285725,0.415011,0.232808] >> [0.144618,0.285725,0.415011,0.232808] >> [0.144618,0.285725,0.415011,0.232808] >> [0.144618,0.285725,0.415011,0.232808] >> #undef >> #undef >> #undef >> #undef >> #undef >> >> Alternatively, the best solution is probably to use a for loop. This >> probably has the semantics that you want, with different uncoupled arrays >> in each spot, and it'll be fast, too: >> >> julia> for idx = 2:5 >> z[idx] = rand(2,2) >> end >> z >> 10-element Array{Array{Float64,2},1}: >> #undef >> [0.691373,0.130612,0.837506,0.255362] >> [0.471128,0.492608,0.602753,0.119473] >> [0.133986,0.793537,0.800129,0.433915] >> [0.922652,0.645796,0.997629,0.982244] >> #undef >> #undef >> #undef >> #undef >> #undef >> >> Matt >> >> On Tuesday, November 3, 2015 at 9:26:49 AM UTC-5, Ján Dolinský wrote: >>> >>> Hi guys, >>> >>> I came across a problem of setting up a (general) subarray with an >>> object (value which is not an ordinary number) e.g. >>> >>> julia> z = Array(Matrix{Float64}, 10) >>> 10-element Array{Array{Float64,2},1}: >>> #undef >>> #undef >>> #undef >>> #undef >>> #undef >>> #undef >>> #undef >>> #undef >>> #undef >>> #undef >>> >>> julia> z[2:5] = rand(2,2) >>> ERROR: MethodError: `convert` has no method matching convert(::Type{ >>> Array{Float64,2}}, ::Float64) >>> This may have arisen from a call to the constructor Array{Float64,2 >>> }(...), >>> since type constructors fall back to convert methods. >>> Closest candidates are: >>> call{T}(::Type{T}, ::Any) >>> convert{T,S,N}(::Type{Array{T,N}}, ::SubArray{S,N,P<:AbstractArray{T,N >>> },I<:Tuple{Vararg{Union{AbstractArray{T,1},Colon,Int64}}},LD}) >>> convert{T,n}(::Type{Array{T,n}}, ::Array{T,n}) >>> ... >>> in setindex! at array.jl:339 >>> >>> What is a "correct" way of doing this ? I can do it via "sub" and >>> "fill!" e.g. >>> >>> julia> zz = sub(z, 2:5) >>> 4-element SubArray{Array{Float64,2},1,Array{Array{Float64,2},1},Tuple{ >>> UnitRange{Int64}},1}: >>> #undef >>> #undef >>> #undef >>> #undef >>> >>> julia> fill!(zz, rand(2,2)) >>> 4-element SubArray{Array{Float64,2},1,Array{Array{Float64,2},1},Tuple{ >>> UnitRange{Int64}},1}: >>> 2x2 Array{Float64,2}: >>> 0.313155 0.553893 >>> 0.74854 0.997401 >>> 2x2 Array{Float64,2}: >>> 0.313155 0.553893 >>> 0.74854 0.997401 >>> 2x2 Array{Float64,2}: >>> 0.313155 0.553893 >>> 0.74854 0.997401 >>> 2x2 Array{Float64,2}: >>> 0.313155 0.553893 >>> 0.74854 0.997401 >>> >>> julia> z >>> 10-element Array{Array{Float64,2},1}: >>> #undef >>> 2x2 Array{Float64,2}: >>> 0.313155 0.553893 >>> 0.74854 0.997401 >>> 2x2 Array{Float64,2}: >>> 0.313155 0.553893 >>> 0.74854 0.997401 >>> 2x2 Array{Float64,2}: >>> 0.313155 0.553893 >>> 0.74854 0.997401 >>> 2x2 Array{Float64,2}: >>> 0.313155 0.553893 >>> 0.74854 0.997401 >>> #undef >>> #undef >>> #undef >>> #undef >>> #undef >>> >>> Thanks, >>> Jan >>> >>
