I am trying to use views to write generic code that can work either with a single vector as an input, operating over numbers, or taking a matrix and operating over vectors (columns of the matrix). Since this is a pretty common need, I am also interested in hearing about how to write code for this kind of thing. But the question is really about a problem I got trying to use views.
The idea is to write a function taking the input and output that I treat as one-dimensional collections of elements. Then for vectors, it all just works. For matrices, I first create the output matrix and then vectors with views for each column of the matrices.
The problem I have is that I canât assign from a vector to the view, even though I can assign from a view. What am I missing here?
a = rand(2, 5)
b = Array{eltype(a)}(undef, size(a)...)
av = [view(a, :, k) for k in 1:size(a, 2)]
bv = [view(b, :, k) for k in 1:size(b, 2)]
av[2] - av[1]
bv[1] = av[2]
bv[1] = av[2] - av[1] # doesn't work
bv[1] = rand(2) # doesn't work
Hereâs a shorter example on the terminal
julia> b = zeros(3, 5)
3Ă5 Array{Float64,2}:
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
julia> bv = [view(b, :, k) for k in 1:size(b, 2)]
5-element Array{SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true},1}:
[0.0, 0.0, 0.0]
[0.0, 0.0, 0.0]
[0.0, 0.0, 0.0]
[0.0, 0.0, 0.0]
[0.0, 0.0, 0.0]
julia> bv[1] = rand(3)
ERROR: MethodError: Cannot `convert` an object of type Array{Float64,1} to an object of type SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}
Closest candidates are:
convert(::Type{T<:AbstractArray}, ::T<:AbstractArray) where T<:AbstractArray at abstractarray.jl:14
convert(::Type{T<:AbstractArray}, ::LinearAlgebra.Factorization) where T<:AbstractArray at /home/user/src/julia/usr/share/julia/stdlib/v1.2/LinearAlgebra/src/factorization.jl:46
convert(::Type{T}, ::T) where T at essentials.jl:154
...
Stacktrace:
[1] setindex!(::Array{SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true},1}, ::Array{Float64,1}, ::Int64) at ./array.jl:767
[2] top-level scope at REPL[78]:1
julia>