How to deal with Index exceeds the number of array elements??

2 views (last 30 days)
Tomaszzz on 14 Feb 2022
Commented: Walter Roberson on 14 Feb 2022
Hi all,
I have a structure with tables (attached) which are diffrent signals collected at the same time with five sensors. Although the signals were collected at the same time from all sensors, one sensor (red below) collected less data.
I am using data from one sensor (table 5) to identify certain indices to extract signal from all sensors between corresponding indices in this manner:
%Indentified indices
indices = [225,250,308,366,425,484,542,601,660,697,1268,1326,1385,1444,1501,1560,1618,1678,1737,1796,1857,1917];
%get data
% Get data between coressponding indices into cells
a = indices ;
n = length(a)-1;
P_or_z_cycle = cell(n,1) ; %here just one variable from a table but I have like 20 to extract
%Fill in the above cell with data between coressponding indices into cells
for i = 1:n
P_or_z_cycle{i} = P_or_z(a(i):a(i+1))
end
which in this example gives me error
Index exceeds the number of array elements (1895).
I know this is beacuse I have one index '1917' but not sure how to modify the code to account for this. There might be more than one indices that exceeds the array lenghts in a particular sensor.
Can you help?
Tomaszzz on 14 Feb 2022
Thanks Walter, just ignore those indices

AndresVar on 14 Feb 2022
Edited: AndresVar on 14 Feb 2022
You could pad the missing data with 0 or nan.
Anyway if you want to ignore the incomplete cycle just check out-of-bounds and continue:
clear
tabs = Data.Data
tab = tabs(3).Dot_Data;
indices = [225 250 2000 2009]; % this for example
n = numel(indices)-1;
P_or_z_cycle = cell(n,1);
for ii = 1:n
idx_lims = [indices(ii) indices(ii+1)];
if (idx_lims(2)>tab.PacketCounter(end))
continue % skip this incomplete cycle
end
idxs = tab.PacketCounter>=idx_lims(1) & tab.PacketCounter<=idx_lims(2); % or just use idx_lims since packetcounter is the same
end
P_or_z_cycle

Walter Roberson on 14 Feb 2022
%Indentified indices
indices = [225,250,308,366,425,484,542,601,660,697,1268,1326,1385,1444,1501,1560,1618,1678,1737,1796,1857,1917];
%get data
% Get data between coressponding indices into cells
a = indices ;
n = length(a)-1;
P_or_z_cycle = cell(n,1) ; %here just one variable from a table but I have like 20 to extract
%Fill in the above cell with data between coressponding indices into cells
for i = 1:n
if a(i) > numel(a); continue; end
P_or_z_cycle{i} = P_or_z(a(i): min(a(i+1), numel(a)));
end
In this code, if the start position is greater than the number of elements, then the P_or_z_cycle{i} will end up as the empty array. If the start position is in range but the end position is not, then the P_of_z_cycle{i} will be the part that exists in the array.
Walter Roberson on 14 Feb 2022
You said to ignore those indices. That is not clear as to what you want to have happen to the cell array locations where the values would go if there was otherwise enough data. Do you want the cell array to be empty in those positions? Do you want there to be no entries at all there, with the cell array ending up smaller than you pre-allocated, with you having lost track of which cell array positions correspond to which indices locations?
Is it guaranteed that indices will always be in increasing order, so that you can just truncate the cell array at the first place that goes too far? That is not something that I can assume without being told, as it could just be a coincidence that the values in your code are sorted.
Note: as you seem to be breaking up the vector into contiguous segments, then mat2cell() could also be used.