using logical indexing to find events

4 ビュー (過去 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 ExchangeMatrix Indexing についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by