Borrar filtros
Borrar filtros

How do I iterate over vector elements, but ignore elements which do not meet a condition?

6 visualizaciones (últimos 30 días)
I have a piece of code, which I'm trying to make run faster. I've used the profiler and most of the time is spent on the following snippet:
for det = 1:N
if detect_vec(det)
result((det+1):(det+deadTime), m0, h) = zeros([1, deadTime]);
end
end
What this is doing is iterating over an array detect_vec which is binary data - each element is a 1 or a 0. If there is a 1, it then sets any other 1s following it to 0. deadTime is a variable which defines how many values after a 1 should be set to 0.
I'm sure there must be a way to make this more efficient; N is very large and so it makes sense that the profiler says the code spends most of its time here. I've tried using the find function by doing the following;
for det = find(detect_vec)
if detect_vec(det)
result((det+1):(det+deadTime), m0, h) = zeros([1, deadTime]);
end
end
This code runs without error but returns many more 1s than I'm expecting, and isn't really any quicker.
Any advice would be great.
  4 comentarios
dpb
dpb el 11 de Dic. de 2020
Unless the separation of elements in detect_vec is >deadTime you'll be resetting elements multiple times and moving the location of the string of zeros along with it.
Is this intended behavior? You could otherwise increment by the gap at least. Whether this reduces iterations or not would depend on the relative values and number of detection locations.
You may want to look at fillmissing with the 'MaxGap' option (if you have R2020b, I think is required).
Daniel Pollard
Daniel Pollard el 11 de Dic. de 2020
The seperation of 1s in detect_vec is random, but on average larger than deadTime. The idea is to eliminate the possibility that detections made are not independent, so any that are too soon after another are set to zero.

Iniciar sesión para comentar.

Respuesta aceptada

Matt J
Matt J el 11 de Dic. de 2020
Editada: Matt J el 11 de Dic. de 2020
z=zeros(1,deadTime);
for det = find(detect_vec);
result((det+1):(det+deadTime), m0, h) = z;
end
  1 comentario
Daniel Pollard
Daniel Pollard el 11 de Dic. de 2020
Thank you so much for all your suggestions. I've tried all of them, and this one seems the most promising. I appreciate the effort you went to to help me.

Iniciar sesión para comentar.

Más respuestas (2)

Matt J
Matt J el 11 de Dic. de 2020
Editada: Matt J el 11 de Dic. de 2020
e=zeros(1,deadTime);
I=conv( double(detect_vec~=0), [e+1,0,e] , 'same')>0;
result(I, m0, h)=0;
  2 comentarios
Daniel Pollard
Daniel Pollard el 11 de Dic. de 2020
This runs perfectly, and gives the same results as my previous code, but it runs takes twice as long to run as my code. Is there a way I can optimize the convolution? That's where the profilier says the code is bottlenecking.
Matt J
Matt J el 11 de Dic. de 2020
Maybe use FFTs to do the convolution, or maybe,
e=ones(1,deadTime);
I=conv( double(detect_vec~=0), [e,0] , 'same')>0;
result(I, m0, h)=0;

Iniciar sesión para comentar.


Matt J
Matt J el 11 de Dic. de 2020
Editada: Matt J el 11 de Dic. de 2020
Using interpMatrix from the File Exchange,
A=interpMatrix([0;ones(deadTime,1)],1,N,1); %compute only once and reuse!!!
result( A*detect_vec(:)>0 ,m,h)=0;

Categorías

Más información sobre Operating on Diagonal Matrices en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by