How to use logical indexing to return elements of a signal?
    8 visualizzazioni (ultimi 30 giorni)
  
       Mostra commenti meno recenti
    
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
0 Commenti
Risposta accettata
  Star Strider
      
      
 il 14 Lug 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
.
0 Commenti
Più risposte (1)
  dpb
      
      
 il 14 Lug 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.
0 Commenti
Vedere anche
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


