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

1 次查看(过去 30 天)
%% 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 个评论
Rik
Rik 2020-6-26
编辑:Rik 2020-6-26
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

请先登录,再进行评论。

采纳的回答

Star Strider
Star Strider 2018-11-29
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 个评论
Star Strider
Star Strider 2018-11-29
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 2020-6-26
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?

请先登录,再进行评论。

更多回答(0 个)

标签

尚未输入任何标签。

产品


版本

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by