Any efficient way to identify a set of 1s in a big array?

1 vue (au cours des 30 derniers jours)
Jaya
Jaya le 3 Sep 2021
Modifié(e) : Stephen23 le 6 Déc 2021
I have an array called link_slots of 800 elements made of 1, 0 and -1.
E.g. 1 1 1 -1 0 0 0 0 1 1 -1 0 0 1 1 1 1 -1 0 0 .... So, 1 denotes occupied, 0 for unoccupied and -1 just to mark the end of a set of 1s.
I want to know the start and end indices of each set of 1s. E.g.,here, start as [1,9,14] and end as [3,10,17]. My code works but found out through Profiler that it takes a lot of time. Is there any efficient way to solve this? Considering that I have to do this thing for multiple arrays for size 800 elements.
i=1;
while(i<numel(link_slots(1,:)) ) %to cycle through whole array
j=i
if(link_slots(1,i)==1) %i.e. if occupied
startt(i)=i %store it in the start array
j=i
while(link_slots(index,j+1)~=-1)
j=j+1
end
endd(i)=j %store the end index upon encountering -1
end
i=j+1
end

Réponse acceptée

Stephen23
Stephen23 le 4 Déc 2021
Modifié(e) : Stephen23 le 6 Déc 2021
A simple, efficient, robust solution:
a = [1,1,1,-1,0,0,0,0,1,1,-1,0,0,1,1,1,1,-1,0,0];
d = diff([false,a==1,false]);
s = find(d>0) % start
s = 1×3
1 9 14
e = find(d<0)-1 % end
e = 1×3
3 10 17
And tested on your new data set:
a = [1,1,-1,1,1,1,-1,0,0];
d = diff([false,a==1,false]);
s = find(d>0) % start
s = 1×2
1 4
e = find(d<0)-1 % end
e = 1×2
2 6
  1 commentaire
Jaya
Jaya le 4 Déc 2021
Modifié(e) : Jaya le 4 Déc 2021
Thank you so much. I want to accept your answer as well. Thinking that my comments on a old question won't be visible to wider audience, I asked a fresh question linking to this question here. You may please paste your answer there so that I can accept it there.

Connectez-vous pour commenter.

Plus de réponses (1)

Ive J
Ive J le 3 Sep 2021
Try this
a = [1 1 1 -1 0 0 0 0 1 1 -1 0 0 1 1 1 1 -1 0 0];
astart = [1, 9, 14];
astop = [3, 10, 17];
dda = diff([0, 0, diff(a)]);
start = find(dda == 1);
if a(1) > 0
start = [1, start];
end
stop = find(circshift(a < 0, -1));
all(astart == start)
ans = logical
1
all(astop == stop)
ans = logical
1
  2 commentaires
Jaya
Jaya le 4 Sep 2021
This really helped to speed up the implementation. Thanks.
Jaya
Jaya le 4 Déc 2021
Modifié(e) : Jaya le 4 Déc 2021
@Ive J Hello, I am the same person who asked the original question. Your solution worked perfectly. But now I find that when my array is like below then it isn't able to identify the start properly. But stop is ok.
a=[1 1 -1 1 1 1 -1 0 0];
%start is only coming as -1 It should instead come as [1 4]
%stop is working fine. I.e. [2 6]
The difference w.r.t the original question array and this array is only that now, the set of 1s are next to another set of 1s separated by the marker, -1. Whereas in the original question, there were some 0's in between. Can you please help me on this?

Connectez-vous pour commenter.

Catégories

En savoir plus sur Matrix Indexing dans Help Center et File Exchange

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by