Say I have an n x m Matrix, and an n-length Vector that I want to copy to, say, column 2 of my matrix. My first try was to do copyto! using CartesianIndices.
m = rand(3,3)
v = rand(3)
copyto!(m, CartesianIndices((1:3, 2:2)), v, CartesianIndices(1:3))
But that fails. copyto! only works to copy a slice of an AbstractArray{T1,N} to another slice of an AbstractArray{T2,N}, i.e. between tensors with the same number of indices, despite the API very elegantly allows to express the more general case with N1 != N2 as above. What is the proper way to do this (for arbitrary N1, N2) in v1.0? Is there a reason why we would not want a more general copyto!?
Something like the following (slight modification of the version in Base) seems to work for me. It’s such a minor modification that I suspect somebody had a good reason not to do it…
function copyto!(dest::AbstractArray{T1,N1}, Rdest::CartesianIndices{N1}, src::AbstractArray{T2,N2}, Rsrc::CartesianIndices{N2}) where {T1,T2,N1,N2}
checkbounds(dest, first(Rdest))
checkbounds(dest, last(Rdest))
checkbounds(src, first(Rsrc))
checkbounds(src, last(Rsrc))
src′ = unalias(dest, src)
for (Is, Id) in zip(Rsrc, Rdest)
@inbounds dest[Id] = src′[Is]
end
return dest
end
No, that works perfectly well, and it’s probably the truly Julian approach. The (small) problem is that, if I understand correctly, that approach allocates a view, and is therefore somewhat slower than a direct copy. Until we have something like #14955 I prefer to avoid views in my particular application. But thanks for pointing that out!
Note, that it only allocates a view of you have a slice on the rhs of the assignment. For copying a full vector (or matrix), as in your original example, it should be efficient.
It sure would be great if could work as efficiently as copyto!. Much simpler, and nicer, I would gladly use .= always and stop worrying about hidden allocations.