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

1 visualizzazione (ultimi 30 giorni)
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

Risposta accettata

Stephen23
Stephen23 il 4 Dic 2021
Modificato: Stephen23 il 6 Dic 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 Commento
Jaya
Jaya il 4 Dic 2021
Modificato: Jaya il 4 Dic 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.

Accedi per commentare.

Più risposte (1)

Ive J
Ive J il 3 Set 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 Commenti
Jaya
Jaya il 4 Set 2021
This really helped to speed up the implementation. Thanks.
Jaya
Jaya il 4 Dic 2021
Modificato: Jaya il 4 Dic 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?

Accedi per commentare.

Categorie

Scopri di più su Loops and Conditional Statements in Help Center e File Exchange

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by