using logical indexing to find events

1 回表示 (過去 30 日間)
William Rose
William Rose 2021 年 12 月 16 日
コメント済み: Mathieu NOE 2021 年 12 月 17 日
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.

採用された回答

Mathieu NOE
Mathieu NOE 2021 年 12 月 16 日
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');

その他の回答 (2 件)

Steven Lord
Steven Lord 2021 年 12 月 16 日
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 件のコメント
William Rose
William Rose 2021 年 12 月 16 日
@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.

サインインしてコメントする。


William Rose
William Rose 2021 年 12 月 16 日
@Mathieu NOE, Thank you very much!
  1 件のコメント
Mathieu NOE
Mathieu NOE 2021 年 12 月 17 日
My pleasure !

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by