How can I make this find function in a for loop run faster using vectorization?

1 visualización (últimos 30 días)
%% Find Peaks of raw data
tic
if MinPeakDistance == 0
[y_enc, t_pks] = findpeaks(y_raw, freq_s, 'MinPeakProminence', MinPeakProminence);
else
[y_enc, t_pks] = findpeaks(y_raw, freq_s,'MinPeakDistance', MinPeakDistance);
end
toc
%% Find Threshold Points on Rising Edge (threshold value = 2)
x1 = NaN(length(t_pks),1);
x2 = NaN(length(t_pks),1);
y1 = NaN(length(t_pks),1);
y2 = NaN(length(t_pks),1);
y = NaN(length(t_pks)-1,1);
x = NaN(length(t_pks)-1,1);
for i=1:length(t_pks)-1 %trying to find a point above and below the threshold then interpolating for the point at y = 2
ind_y = find(t_raw < t_pks(i+1)& t_raw>t_pks(i));
threshold_pt = find(y_raw(ind_y)<2,1,'last');
x0 = threshold_pt;
y1(i) = y_raw(ind_y(x0));
x1(i) = t_raw(ind_y(x0));
y2(i) = y_raw(ind_y(x0)+1);
x2(i) = t_raw(ind_y(x0)+1);
y(i) = 2;
x(i) = (y(i)-y1(i))*(x2(i)-x1(i))/(y2(i)-y1(i)) + x1(i);
end
  2 comentarios
Rik
Rik el 26 de Jun. de 2020
Editada: Rik el 26 de Jun. de 2020
Question posted by doyi joo on 29 Nov 2018 restored from Google cache:
How can I make this find function in a for loop run faster using vectorization?
%% Find Peaks of raw data
tic
if MinPeakDistance == 0
[y_enc, t_pks] = findpeaks(y_raw, freq_s, 'MinPeakProminence', MinPeakProminence);
else
[y_enc, t_pks] = findpeaks(y_raw, freq_s,'MinPeakDistance', MinPeakDistance);
end
toc
%% Find Threshold Points on Rising Edge (threshold value = 2)
x1 = NaN(length(t_pks),1);
x2 = NaN(length(t_pks),1);
y1 = NaN(length(t_pks),1);
y2 = NaN(length(t_pks),1);
y = NaN(length(t_pks)-1,1);
x = NaN(length(t_pks)-1,1);
for i=1:length(t_pks)-1 %trying to find a point above and below the threshold then interpolating for the point at y = 2
ind_y = find(t_raw < t_pks(i+1)& t_raw>t_pks(i));
threshold_pt = find(y_raw(ind_y)<2,1,'last');
x0 = threshold_pt;
y1(i) = y_raw(ind_y(x0));
x1(i) = t_raw(ind_y(x0));
y2(i) = y_raw(ind_y(x0)+1);
x2(i) = t_raw(ind_y(x0)+1);
y(i) = 2;
x(i) = (y(i)-y1(i))*(x2(i)-x1(i))/(y2(i)-y1(i)) + x1(i);
end

Iniciar sesión para comentar.

Respuesta aceptada

Star Strider
Star Strider el 29 de Nov. de 2018
Try this:
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector
x = linspace(0, 8*pi, 150); % Create Data
y = 3*sin(x); % Create Data
y2idx = zci(y-2); % Approximate Indices Where y=2
for k1 = 1:numel(y2idx)
idxrng = [y2idx(k1)-1 y2idx(k1)+1];
b = [x(idxrng(1)) 1; x(idxrng(2)) 1]\y(idxrng).'; % Calculate Linear Fit
xy2(k1) = (2-b(2))/b(1); % Evaluate Linear Fit
end
figure
plot(x, y)
hold on
plot(xy2, 2*ones(size(xy2)), 'x')
hold off
grid
It uses a little utility function ‘zci’ to calculate the zero-crossing indices (with ‘zero’ is defined here as +2), then loops through the indices, calculating a linear fit and then doing the interpolation at each step, returning the interpolated x-value in the ‘xy2’ vector. The plot simply shows the results, and how to use them.
  2 comentarios
Star Strider
Star Strider el 29 de Nov. de 2018
My pleasure!
I did not have your data to work with, so I created my own data to illustrate the approach.
Yes. I wrote ‘zci’ for my own use originally.
If my Answer helped you solve your problem, please Accept it!
Rik
Rik el 26 de Jun. de 2020
Comment restored from Google cache:
Hi, thanks for replying!
I tried to use it...basically substituting your X and Y with my datasets. I get Subscript indices must either be real positive integers or logicals.error. I am not sure what is happening in the for loop to figure out how to mitigate it...
Comment restored from Google cache:
I figured it out!
Thank you so much!
Did you write the ZCI Function?

Iniciar sesión para comentar.

Más respuestas (0)

Etiquetas

Aún no se han introducido etiquetas.

Productos


Versión

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by