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
>

Reply via email to