Matlab: Rollingwindow matrix with different intervals between columns
I have a vector of data for 21 years with daily data and want to create a rolling window of 365 days such as the next period stars one month (30 days) after the previous one. In the question, n_interval
defines the difference between the first data point of the next window and the last observation of the previous series.
Let's assume my daily data start from Jan. 1 2000, then the first column would be Jan. 1, 2000 Jan.1, 2001 and the second column starts from Feb. 1, 2000. and ends on Feb. 1, 2001. and ... the last column will cover Jan. 1, 2017 to Jan. 1, 2018. for example if:
vec = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17]
for a given variable n_interval = 3
, with window_size=5
, the output matrix should look like:
mat = [[1 4 7 10 13],
[2 5 8 11 14],
[3 6 9 12 15],
[4 7 10 13 16],
[5 8 11 14 17]]
Any help would be appreciated.
1 answer

Given your example vector
vec = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17];
we can create an indexing scheme by as follows:
First, we need to determine how many rows there will be in the
mat
. Assuming we want every element ofvec
to be expressed inmat
at least once then we need to make sure that last index in the last row is greater than or equal to the size ofvec
. It's fairly easy to see that the index of the last column inmat
is described bylast_index = n_interval*(n_rows1) + n_columns
We want to ensure that
last_index >= numel(vec)
. Substituting in the above expression into the inequality and solving forn_rows
givesn_rows >= (numel(vec)  n_columns)/n_interval + 1
We assign
n_rows
to be theceil
of this bound so that it is the smallest integer which satisfies the inequality. Now that we know the number of rows we generate the list of starting indices for each rowstart_index = 1:n_interval:(n_interval*(n_rows1)+1);
In the index matrix we want each column to be 1 plus the previous column. In other words we want to offset the column according to the array
index_offset = 0:(n_interval1)
.Using
bsxfun
we generate the index matrix by computing the sums of all pairs between thestart_index
andindex_offset
arraysindex = bsxfun(@plus, index_offset, start_index');
The final thing we need to worry about is going out of bounds. To handle this we apply the
mod
function to wrap the out of bounds indicies:index_wrapped = mod(index1, numel(vec))+1;
Then we simply sample the vector according to
index_wrapped
mat = vec(index_wrapped);
The complete code is
n_interval = 3; n_columns = 5; vec = 1:17; n_rows = ceil((numel(vec)n_columns)/n_interval + 1); start_index = 1:n_interval:(n_interval*(n_rows1)+1); index_offset = 0:(n_columns1); index = bsxfun(@plus, index_offset, start_index'); index_wrapped = mod(index1, numel(vec))+1; mat = vec(index_wrapped);