using logical indexing to find events

1 view (last 30 days)
I have three vectors of the same length: t, x, y. I also have tevent, whose elements are a subset of the elements in t. Can I use logical indexing, without a for loop, to find all the elements of x and y whose times are the times in tevent?
Example:
t=0:0.01:10; x=sin(2*pi*t)+t/10; y=sin(2*pi*t+pi/4);
tevent=[5.3,3.2,8.7,2,0.9];
%xevent=x(t==tevent)); %I wish this would work, but it causes an error.
%Next line is not practical when tevent has many elements,
%and is impossible, if length(tevent) is not known in advance.
xevent=x(t==tevent(1)|t==tevent(2)|t==tevent(3)|t==tevent(4)|t==tevent(5));
yevent=y(t==tevent(1)|t==tevent(2)|t==tevent(3)|t==tevent(4)|t==tevent(5));
%for loop works, but seems ugly
xe2=zeros(size(tevent)); ye2=xe2;
for i=1:length(tevent)
xe2(i)=x(t==tevent(i));
ye2(i)=y(t==tevent(i));
end
plot(x,y,'-r',xevent,yevent,'bx',xe2,ye2,'g+');
There must be a better way than what I did above.
Another thing: certain event times do not get found by the search above. I guess this is a rounding thing. For example, the line below should find two values in the vector t, but it fails to find the element t=5.4.
fprintf('Find and print two values: %.1f, %.1f.\n',t(t==5.3),t(t==5.4));
Find and print two values: 5.3, .
A workaround is
fprintf('Find and print two values: %.1f, %.1f.\n',t(abs(t-5.3)<1e-6),t(abs(t-5.4)<1e-6));
Find and print two values: 5.3, 5.4.
Thanks in advance.

Accepted Answer

Mathieu NOE
Mathieu NOE on 16 Dec 2021
hello
there is a very simple answer using interp1
t=0:0.01:10; x=sin(2*pi*t)+t/10; y=sin(2*pi*t+pi/4);
tevent=[5.3,3.2,8.7,2,0.9];
xevent=interp1(t,x,tevent);
yevent=interp1(t,y,tevent);
plot(x,y,'-r',xevent,yevent,'bd');

More Answers (2)

Steven Lord
Steven Lord on 16 Dec 2021
Use ismembertol (to avoid floating-point issues) or ismember (if your time data contains exactly represtentable times.)
t=0:0.01:10;
x=sin(2*pi*t)+t/10;
y=sin(2*pi*t+pi/4);
tevent=[5.3,3.2,8.7,2,0.9];
eventLocations = ismembertol(t, tevent);
tsort = sort(tevent);
times = [t(eventLocations); tsort]
times = 2×5
0.9000 2.0000 3.2000 5.3000 8.7000 0.9000 2.0000 3.2000 5.3000 8.7000
checkX = [x(eventLocations); sin(2*pi*tsort)+(tsort/10)]
checkX = 2×5
-0.4978 0.2000 1.2711 1.4811 -0.0811 -0.4978 0.2000 1.2711 1.4811 -0.0811
checkY = [y(eventLocations); sin(2*pi*tsort+pi/4)]
checkY = 2×5
0.1564 0.7071 0.8910 0.4540 -0.8910 0.1564 0.7071 0.8910 0.4540 -0.8910
  1 Comment
William Rose
William Rose on 16 Dec 2021
@Steven Lord, thank you for telling me about ismember() and ismembertol().
I would accept your answer too, if it were possible to accept more than one.

Sign in to comment.


William Rose
William Rose on 16 Dec 2021
@Mathieu NOE, Thank you very much!

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!