Extract submatrix using a sliding window
4 views (last 30 days)
Show older comments
Hi all,
I have a matrix A = [1,2,3;
4,5,6;
7,8,9;
10,11,12;
13,14,15];
I want to derive a second matrix, called A1, which has all the submatrices obtained through a sliding Window W = 2 and a shift delta = 1. I mean, starting from the A above I want to obtain something like:
A1 = [1,2,3;
4,5,6;
4,5,6;
7,8,9;
7,8,9;
10,11,12;
10,11,12;
13,14,15]
I need to do this procedure for a very large matrix A (200.000 rows x 300 columns), is there a way you can suggest me with a good response time from matlab?
Thanks
2 Comments
Guillaume
on 6 Dec 2018
Edited: Guillaume
on 6 Dec 2018
I do not understand how A1 matches your description. With a window of size 2, I'd expect 2x2 submatrices. Maybe,
A1 = cat(3, [1 2; 4 5], [2 3; 5 6], [4 5;7 8], etc.)
but certainly not the A1 you describe.
With a 200,000 x 300 matrix, have you calculated how many submatrices this would generate and how much memory that would require? Do you actually need to store these submatrices. You'll just be storing extremely redundant information.
Answers (2)
Guillaume
on 6 Dec 2018
I don't see how replicating the rows is going to save you time. You're just using more memory to store the same information. However, if it's what you want to do, your A1 is easily obtained, at least for your window of height 2 with shift of 1:
A1 = repelem(A, 2, 1); %replicate each row twice, don't replicate columns
A1 = A1(2:end-1)
For a larger window height (but still shift of 1), you can get your matrix with im2col which requires the image processing toolbox:
A1 = reshape(im2col(A.', [size(A, 2), windowheight]), size(A, 2), []).'
However, this would probably take more time than your existing loop.
For a shift > 1, you probably need to use a loop, which would take as much time as your existing loop.
5 Comments
Guillaume
on 7 Dec 2018
Well, as I keep saying, I don't see the point of that precomputation step. Unless the processing itself can be carried out without a loop, it's not going to give you any speed advantage. If anything you may be doing twice as much wore and you're certainly storing redundant information. Even Jos' method of precomputing the indices is not going to make any significant difference. The expensive part of your loop is the processing, not the calculation of the submatrices.
So, I think you're focusing on the wrong part of the problem. What may needs optimising is that computation you do on the submatrices.
Jos (10584)
on 7 Dec 2018
My advise: create the proper index vector from windowsize and shift and use that to extract the rows
A = [1 2 3; 4 5 6 ; 7 8 9 ; 10 11 12 ; 13 14 15]
windowsize = 3
shift = 2
N = size(A,1)
ix = (1:shift:N) + (0:windowsize-1).'
ix = ix(ix<=N)
B = A(ix,:)
1 Comment
Jos (10584)
on 7 Dec 2018
for N = 1e5, windowsize = 5000 and shift = 10, this takes a second on my old mac :-D
See Also
Categories
Find more on Resizing and Reshaping Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!