0

This is probably simple but here is my problem.

I have two vectors, starts and ends. Starts are the starting points of sequences of consecutive numbers and ends are the end points of sequences of consecutive numbers. I would like to create a vector which contains these runs.

So for example, say

starts = [2 7 10 18 24]  
ends = [5 8 15 20 30]

I would like to create the following vector

ans = [2 3 4 5 7 8 10 11 12 13 14 15 18 19 20 24 25 26 27 28 29 30]

Using starts:end only uses the first element of each vector


I would also like to do this without using a (for) loop in order to keep it as fast as possible!

Thanks for reading

Chris

ssedano
  • 8,322
  • 9
  • 60
  • 98

2 Answers2

2

Assuming there's always the same number of start and end points, and they always match (e.g. the nth start corresponds to the nth end), then you can do

cell2mat(arrayfun(@(s,e) (s:e), starts, ends, 'UniformOutput', false))

For a bit more detailed explanation, the arrayfun(@(s,e) (s:e), starts, ends, 'UniformOutput', false) part will generate a sequence of n cell arrays, where n is the length of the starts and ends vectors, such that each cell array has the sequence starts(i):ends(i) corresponding to the ith elements of the two vectors. Then the cell2mat function will fuse each of the individual cell arrays into 1 larger matrix.

alrikai
  • 4,123
  • 3
  • 24
  • 23
0

When you're worried about making it fast, preallocate:

starts = [2 7 10 18 24]  
ends = [5 8 15 20 30]
a = zeros(1,sum(ends)+numel(ends)-sum(starts));
% or a = zeros(1,sum(ends+1-starts))
j = 1;
for i = 1:numel(ends)
    j2 = j+ends(i)-starts(i);
    a(j:j2) = (starts(i):ends(i));
    j = j2+1;
end
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720