FIND function with multiple conditions
11 次查看(过去 30 天)
显示 更早的评论
Hello!
I have a dataset, state, that is 500x6 data. This dataset presents position and velocity for a circular orbit. As a result, there are cases where an x-position might have 2 options for y-location (1 positive, 1 negative).
The second data, p, set is 1x6: the final position and velocity at the end of an arc. This data may have either positive or negative for y-location for each computation.
The goal is to search the 500x6 data set to find the location (index) where p(1,1:3) = state(i,1:3). The goal is to match position only.
I have tried the following:
temp = min(abs(p(1,1:3) - state(:,1:3))) % tolerance
location = find(abs(p(1,1:3) - state(:,1:3)) == temp)
This method works when the y-location is positive for both z and state. It correctly finds the location in state.
Any recommendations on how to modify the search to correctly find the index when the y-location is negative in both sets? Thank you!
0 个评论
回答(1 个)
Mathieu NOE
2021-3-15
hello Nadia
I have tried another approach , by looking at the 2 nearest points to zero crossing points of the vector defined as the difference between position and state .
the index of the 2 points is stored in ind_close
I have tested my code on dummy data
hope it works for you
% dummy data
theta = 0:0.1:2*pi;
p = sin(theta);
s = 0.5*cos(theta);
figure(1),plot(theta,p,'b',theta,s,'r');
legend(' data : position', 'data : state')
%%%%%%%%%%%%%%%%%%% main loop %%%%%%%%%%%%%%%%%%%%%%%%%
dd = p - s; % difference
[ind,theta0,dd0,ind_close,theta0_close,dd0_close] = crossing_V6(dd,theta,0,'linear'); % Zero-Crossing
figure(2)
plot(theta, dd, '*r')
hold on
plot(theta0_close, dd0_close, 'bp')
hold off
grid on
legend('p - s difference', 'nearest points to Zero-Crossings points')
% save data
p(ind_close)
s(ind_close)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ind,t0,s0,indclose,t0close,s0close] = crossing_V6(S,t,level,imeth)
% [ind,t0,s0,t0close,s0close] = crossing_V6(S,t,level,imeth)
% CROSSING find the crossings of a given level of a signal
% ind = CROSSING(S) returns an index vector ind, the signal
% S crosses zero at ind or at between ind and ind+1
% [ind,t0] = CROSSING(S,t) additionally returns a time
% vector t0 of the zero crossings of the signal S. The crossing
% times are linearly interpolated between the given times t
% [ind,t0] = CROSSING(S,t,level) returns the crossings of the
% given level instead of the zero crossings
% ind = CROSSING(S,[],level) as above but without time interpolation
% [ind,t0] = CROSSING(S,t,level,par) allows additional parameters
% par = {'none'|'linear'}.
% With interpolation turned off (par = 'none') this function always
% returns the value left of the zero (the data point thats nearest
% to the zero AND smaller than the zero crossing).
%
% [ind,t0,s0] = ... also returns the data vector corresponding to
% the t0 values.
%
% [ind,t0,s0,t0close,s0close] additionally returns the data points
% closest to a zero crossing in the arrays t0close and s0close.
%
% This version has been revised incorporating the good and valuable
% bugfixes given by users on Matlabcentral. Special thanks to
% Howard Fishman, Christian Rothleitner, Jonathan Kellogg, and
% Zach Lewis for their input.
% Steffen Brueckner, 2002-09-25
% Steffen Brueckner, 2007-08-27 revised version
% M Noé , 2020-08-20 revised version
% Copyright (c) Steffen Brueckner, 2002-2007
% brueckner@sbrs.net
% check the number of input arguments
error(nargchk(1,4,nargin));
% check the time vector input for consistency
if nargin < 2 | isempty(t)
% if no time vector is given, use the index vector as time
t = 1:length(S);
elseif length(t) ~= length(S)
% if S and t are not of the same length, throw an error
error('t and S must be of identical length!');
end
% check the level input
if nargin < 3
% set standard value 0, if level is not given
level = 0;
end
% check interpolation method input
if nargin < 4
imeth = 'linear';
end
% make row vectors
t = t(:)';
S = S(:)';
% always search for zeros. So if we want the crossing of
% any other threshold value "level", we subtract it from
% the values and search for zeros.
S = S - level;
% first look for exact zeros
ind0 = find( S == 0 );
% then look for zero crossings between data points
S1 = S(1:end-1) .* S(2:end);
ind1 = find( S1 < 0 );
% bring exact zeros and "in-between" zeros together
ind = sort([ind0 ind1]);
% and pick the associated time values
t0 = t(ind);
s0 = S(ind);
if strcmp(imeth,'linear')
% linear interpolation of crossing
for ii=1:length(t0)
%if abs(S(ind(ii))) > eps(S(ind(ii))) % MATLAB V7 et +
if abs(S(ind(ii))) > eps*abs(S(ind(ii))) % MATLAB V6 et - EPS * ABS(X)
% interpolate only when data point is not already zero
NUM = (t(ind(ii)+1) - t(ind(ii)));
DEN = (S(ind(ii)+1) - S(ind(ii)));
slope = NUM / DEN;
t0(ii) = t0(ii) - S(ind(ii)) * slope;
s0(ii) = level;
end
end
end
% Addition:
% Some people like to get the data points closest to the zero crossing,
% so we return these as well
[CC,II] = min(abs([S(ind-1) ; S(ind) ; S(ind+1)]),[],1);
indclose = ind + (II-2); %update indices
t0close = t(indclose);
s0close = S(indclose);
end
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Dates and Time 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!