How to use logical indexing to return elements of a signal?

2 views (last 30 days)
Hi all,
I have a signal like this (attached). My ultimate aim is to return elements of the signal between parts of the signal that are empty and put them in seperate cells as depicted on the image on the right. My approach and a problem is below. Would you mind helping?
load 'signal'
% Replace nan values with 0
force_y_r(isnan(force_y_r))=0;
% find peaks of the both sides of the flat section of the signal
idx_first = islocalmin(force_y_r, 'FlatSelection','first', 'MinSeparation',500, 'MinProminence',750);
idx_last = islocalmin(force_y_r, 'FlatSelection','last', 'MinSeparation',500, 'MinProminence',750);
% THE PROBLEM: find column numerical values in force_y_r that corresponds to idx_first (green) & % idx_last (red)
[row_idx_first,col_idx_first] = find(size(force_y_r),idx_first);
[row_idx_last,col_idx_last] = find(size(force_y_r),idx_last);
this gives me:
Error using find
Second argument must be a positive scalar integer.
% extract parts of the signal between col_idx_first(1) and col_idx_last(1)% col_idx_first(2) and col_idx_last(2)
% and so on
%if col_idx_last occured before col_idx_first
col_idx_last(1) = []
n_start = numel(col_idx_first)-1;
force_y_r_cycle = cell(n_start,1) ;
for i = 1:n_start
force_y_r_cycle{i} = force_y_l(col_idx_first(i):col_idx_last(i+1)) ;
end

Accepted Answer

Star Strider
Star Strider on 14 Jul 2022
Try this —
StartIndices = find(Lv2);
StartIndices = StartIndices(1:end-1);
EndIndices = find(Lv1);
EndIndices = EndIndices(2:end);
for k = 1:numel(StartIndices)
Force{k,:} = force_y_r(StartIndices(k):EndIndices(k));
end
Force
Force1 = Force{1}(1:10) % First 10 Rows
SegmentIndices = table(StartIndices, EndIndices)
producing:
Force =
8×1 cell array
{367×1 double}
{402×1 double}
{402×1 double}
{392×1 double}
{379×1 double}
{379×1 double}
{397×1 double}
{370×1 double}
They must be stored in cell arrays, since they are not all the same sizes. It would be possible to store them in a matrix, however the unused matrix elements for the shorter vectors would be NaN or 0 or whatever the matrix was preallocated to be.
SegmentIndices =
7×2 table
StartIndices EndIndices
____________ __________
1649 2482
2883 3628
4029 4706
5097 5852
6230 6946
7324 8036
8432 9149
To retrieve the contents of the cell arrays:
Force1 = Force{1}
Force1 =
0.0000
31.4198
45.7187
69.0982
82.0834
95.3331
103.3904
114.8121
129.8821
147.0273
.

More Answers (1)

dpb
dpb on 14 Jul 2022
>> whos -file signal
Name Size Bytes Class Attributes
force_y_r 9607x1 76856 double
>>
Your signal is just a vector, not a 2D array so all you need is one-element addressing -- the column is always 1. And, since islocalmin returns a logical array, everything is zero except the true locations and so
idx1=find(idx_first);
idx2=find(idx_last);
is the set of indices you're looking for. I'd not bother with the second variable here, probably, but just overwrite the two you already have. Or, you could write
idx_first=find(islocalmin(force_y_r, 'FlatSelection','first', 'MinSeparation',500, 'MinProminence',750));
from the start.

Community Treasure Hunt

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

Start Hunting!