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

1 visualización (últimos 30 días)
Jaya
Jaya el 3 de Sept. de 2021
Editada: Stephen23 el 6 de Dic. de 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

Respuesta aceptada

Stephen23
Stephen23 el 4 de Dic. de 2021
Editada: Stephen23 el 6 de Dic. de 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 comentario
Jaya
Jaya el 4 de Dic. de 2021
Editada: Jaya el 4 de Dic. de 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.

Iniciar sesión para comentar.

Más respuestas (1)

Ive J
Ive J el 3 de Sept. de 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 comentarios
Jaya
Jaya el 4 de Sept. de 2021
This really helped to speed up the implementation. Thanks.
Jaya
Jaya el 4 de Dic. de 2021
Editada: Jaya el 4 de Dic. de 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?

Iniciar sesión para comentar.

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by