using logical indexing to find events

1 vue (au cours des 30 derniers jours)
William Rose
William Rose le 16 Déc 2021
Commenté : Mathieu NOE le 17 Déc 2021
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.

Réponse acceptée

Mathieu NOE
Mathieu NOE le 16 Déc 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');

Plus de réponses (2)

Steven Lord
Steven Lord le 16 Déc 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 commentaire
William Rose
William Rose le 16 Déc 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.

Connectez-vous pour commenter.


William Rose
William Rose le 16 Déc 2021
@Mathieu NOE, Thank you very much!

Catégories

En savoir plus sur Loops and Conditional Statements dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by