How to find indices of a rectangular region inside big matrix? | Efficiently
Show older comments
How can indices of elements belong to a rectangular region can be found?
A = [4 4 4 4 4 4 4
4 1 1 1 1 3 0
4 1 3 3 1 3 0
4 1 3 3 1 3 0
4 1 1 1 1 3 0
4 4 4 4 4 4 4];

Input: Matrix's size[height, width] , [Row_start Row_end], [Col_start Col_end]
Output: [21 22 23 27 28 29 33 34 35]
Why efficiently : to do same for multiple combinations of rows & columns
Thank you
4 Comments
Caglar
on 2 Nov 2018
How is [3 1 3; 3 1 3; 1 1 3] is a 'rectangle'?
JAI PRAKASH
on 2 Nov 2018
Caglar
on 2 Nov 2018
I am not sure If I understood what you are asking for. If you want to get a part of a matrix you can do it like A(3:5,4:6) .
JAI PRAKASH
on 2 Nov 2018
Accepted Answer
More Answers (2)
Geoffrey Schivre
on 2 Nov 2018
Hello,
I'm not sure if it's efficient enough but try :
p = nchoosek([Row_start:Row_end,Col_start:Col_end],2);
idx = unique(sub2ind(size(A),p(:,1),p(:,2)));
Geoffrey
5 Comments
Geoffrey Schivre
on 2 Nov 2018
Edited: Geoffrey Schivre
on 2 Nov 2018
To find indices of a 10 by 20 bloc in a 1e6 by 1e6 matrix takes less than 10ms :
tic
N = 1e6;
n1 = randi([1,N],1,1);
n2 = randi([1,N],1,1);
p = nchoosek([n1:(n1+9),n2:(n2+19)],2);
idx = unique(sub2ind([N,N],p(:,1),p(:,2)));
toc
Elapsed time is 0.008410 seconds.
The time scale up only with the size of the rectangle you are looking for.
JAI PRAKASH
on 2 Nov 2018
Geoffrey Schivre
on 2 Nov 2018
When you are looking for big rectangle use :
p1 = nchoosek([Row_start:Col_end],2);
p2 = nchoosek([Col_start:Row_end],2);
p3 = intersect([Row_start:Col_end],[Col_start:Row_end]);
p = [p1;p2;[p3',p3']];
idx = sub2ind(size(A),p(:,1),p(:,2));
This methode is less efficient on small rectangle but more efficient on large one due to the use of nchoosek on smaller vectors :
small rectangle (100 by 100) :
tic
N = 10000;
n1 = 10;
n2 = 10;
s1 = 99;
s2 = 99;
p = nchoosek([n1:(n1+s1),n2:(n2+s2)],2);
idx = unique(sub2ind([N,N],p(:,1),p(:,2)));
toc
Elapsed time is 0.016082 seconds.
tic
N = 10000;
n1 = 10;
n2 = 10;
s1 = 99;
s2 = 99;
p1 = nchoosek([n1:(n2+s2)],2);
p2 = nchoosek([n2:(n1+s1)],2);
p3 = intersect([n1:(n2+s2)],[n2:(n1+s1)]);
p = [p1;p2;[p3',p3']];
idx = sub2ind([N,N],p(:,1),p(:,2));
toc
Elapsed time is 0.020043 seconds.
large rectangle (1000 by 1000) :
tic
N = 10000;
n1 = 10;
n2 = 10;
s1 = 999;
s2 = 999;
p = nchoosek([n1:(n1+s1),n2:(n2+s2)],2);
idx = unique(sub2ind([N,N],p(:,1),p(:,2)));
toc
Elapsed time is 21.936548 seconds.
tic
N = 10000;
n1 = 10;
n2 = 10;
s1 = 999;
s2 = 999;
p1 = nchoosek([n1:(n2+s2)],2);
p2 = nchoosek([n2:(n1+s1)],2);
p3 = intersect([n1:(n2+s2)],[n2:(n1+s1)]);
p = [p1;p2;[p3',p3']];
idx = sub2ind([N,N],p(:,1),p(:,2));
toc
Elapsed time is 5.138268 seconds.
Geoffrey Schivre
on 2 Nov 2018
Sorry, I didn't refresh this page so I didn't see that your question was answered. I'm glad you find what you ask for !
JAI PRAKASH
on 2 Nov 2018
function result = stack (A,row_start,row_end,col_start,col_end)
% A = [4 4 4 4 4 4 4
% 4 1 1 1 1 3 0
% 4 1 3 3 1 3 0
% 4 1 3 3 1 3 0
% 4 1 1 1 1 3 0
% 4 4 4 4 4 4 4];
% row_start=3; col_start=4;
% row_end=5; col_end=6;
height=(size(A,1));
result=(row_start:row_end)+(height)*((col_start:col_end)'-1);
result=transpose(result); result=result(:);
end
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!