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

1 visualizzazione (ultimi 30 giorni)
%% 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 Commenti
Rik
Rik il 26 Giu 2020
Modificato: Rik il 26 Giu 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

Accedi per commentare.

Risposta accettata

Star Strider
Star Strider il 29 Nov 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 Commenti
Star Strider
Star Strider il 29 Nov 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 il 26 Giu 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?

Accedi per commentare.

Più risposte (0)

Tag

Non è stata ancora inserito alcun tag.

Prodotti


Release

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by