Now I would like to transform it into a fixed number of groups, e.g. r = 3, stored in a Matrix this way:
1 2 3 4 5 6 7
2 3 4 5 6 7 8
3 4 5 6 7 8 9
I could fill a new Matrix with loops, but for performance reason, I’d prefer not to copy the values, so I guess using @view would be better.
I don’t know what would be a clever way to do that.
For those of us not as smart as mikmoore, an alternative:
using LazyStack
using ShiftedArrays: circshift as SA_circshift
data = [1,2,3,4,5,6,7,8,9]
n = length(data)
r = 3
m = transpose(lazystack(view(SA_circshift(data, i), 1:n-r+1) for i in 0:-1:-r+1))
LazyStack.stack does not work with this type of iterator
julia> @btime LazyStack.stack(partition($data,3,1))
ERROR: MethodError: no method matching stack(::IterTools.Partition{Vector{Int64}, 3, 1})
You may have intended to import Base.stack
it is certainly very flexible (being able to choose as parameters the number of rows and the shift) and easy to use.
Maybe it would be even better if lazystack were to put together the pieces of the partition.
Honestly, I wouldn’t be surprised if such views performed worse than copying the data. Copies are surprisingly cheap. And accessing views — especially views that use non-range indices — can be surprisingly expensive. The tradeoff will depend upon how you use the view.
Profile!
It’s also worth noting that you can just index directly with a matrix of indices. Or broadcast. And with broadcasting, you can possibly fuse with downstream operations, too.
You don’t. I quickly browsed the readme for ToeplitzMatrices.jl and it looked like it was useful, but on closer inspection that only applies to circulant matrices. Will edit my post.
On even closer inspection: multiplying by a large Toeplitz (or Hankel) matrix is done using an FFT. So even though. FFTW is not needed for the small example, it is likely to be useful in practice.