In a logical array index the area with the most TRUE values

Below I have a logical vector:
t=[0 1 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 1 0];
which has 5 TRUE areas and 6 FALSE areas. The 3rd TRUE area has the most TRUE elements of all TRUE areas.
How can I index it logically? To be more specific I want to get the following result:
t=[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0];
Thank you!

 Accepted Answer

t=[0 1 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 1 0];
ii = 3;
out = cumsum([false;diff(t(:))==1]) == 3 & t(:);
or
a = cumsum([false;diff(t(:))==1]);
aa = a(t>0);
[~,ii]=max(histc(aa,unique(aa))); % or: [~,ii]=max(accumarray(aa,aa,[],@numel));
out = a == 3 & t(:);
or with Image Processing Toolbox
C = bwlabel(t);
Z = regionprops(C,'Area');
[~,ii] = max([Z.Area]);
out = C == ii;
or mix
[~,ii] = min(strfind([0,t(:)'],[0 1])-strfind([t(:)',0],[1 0]));
out = ii == bwlabel(t(:)');

6 Comments

Thank you! But how you find that ii=3 in this case?
Hi Giorgos! About ii in after or.
Just one remark! In the case that the vector t starts with TRUE and also the area with the most TRUE values is the first area, then:
out = a == 3 & t(:);
fails to give the correct result. This is because
a = cumsum([false;diff(t(:))==1]);
and not
a1 = cumsum(diff([0; t'])==1)
It's better to place a zero and then diff. (as also Azzi does with:
a=find(diff([0 t 0]));
)
I agree. Use a = cumsum(diff([0;t(:)])==1);
Thank you Andrei for the complete and extensive answer!

Sign in to comment.

More Answers (1)

t=[0 1 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 1 0];
a=find(diff([0 t 0]));
idx1=a(1:2:end);
idx2=a(2:2:end)-1;
[~,nmax]=max(idx2-idx1);
t=zeros(1,numel(t));
t(idx1(nmax):idx2(nmax))=1

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!