# Extracting multiple signal segments without a for loop

4 views (last 30 days)
Nikola Grujic on 18 Apr 2024
Edited: Bruno Luong on 18 Apr 2024
If I have a vector signal, how may I extract certain segments if I have the indices of the beginning of these segments (and I want to take for example 100 points after each segment onset, and arrange them in a nSegments by 100 matrix?
This is easy to do in a for loop (see example below), but I would love to find a vectorized way to do it, without a loop, if it is even possible.
signal = rand(1000,1);
segmentOnsetIndices = [50 120 550 600 750];
for idx = 1:length(segmentOnsetIndices)
signalSegments(idx,:) = signal(segmentOnsetIndices(idx):segmentOnsetIndices(idx)+100)
end

Bruno Luong on 18 Apr 2024
As you like but this code is perhaps slower than the for-loop
signal = rand(1000,1);
segmentOnsetIndices = [50 120 550 600 750];
signalSegments = signal(segmentOnsetIndices(:) + (0:100));
Nikola Grujic on 18 Apr 2024
That is awesome. I tested it with tic toc and it is slightly faster on this small example. Probably when scaling up it can save a bit of time. An alternative I found was extractsigroi function.
More importantly, it saves space (1 line vs 3) :)
Thanks
Bruno Luong on 18 Apr 2024
Edited: Bruno Luong on 18 Apr 2024
Be aware that if segmentOnsetIndices has 1 element your outcome suddently become 101 row vector and not 101 column array. Short syntax but dangeruous for potential bug.
signal = rand(1000,1);
segmentOnsetIndices = 123; % [50 120 550 600 750];
signalSegments = signal(segmentOnsetIndices(:) + (0:100));
size(signalSegments)
ans = 1x2
101 1
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
To secure such change orientation, you could do
idx = segmentOnsetIndices(:) + (0:100);
signalSegments = signal(idx);
signalSegments = reshape(signalSegments, size(idx));
It ends up with three lines of code and more obscure than the for-loop IMO.
Another way to avoid oriebtation issue is to decide by design that the segments are orientaed as the source vector, meaninf in your case (101 x n) where n is the number of segments (length segmentOnsetIndices). This of course assumes the segments stay as non-scalar.