Creating a sequence of vectors of starting and ending numbers

How can I create a sequence if I have vectors of the initial and final number of subsequences in a vector in Matlab?

Input Example:

A=[12 20 34]  
B=[18 25 37]

I want to get (distance for clarity):

C=[12 13 14 15 16 17 18    20 21 22 23 24 25    34 35 36 37]
+4
source share
5 answers

Assuming that Aboth Bare sorted in ascending order and what B(i) < A(i+1)is done then:

idx = zeros(1,max(B)+1);
idx(A) = 1;
idx(B+1) = -1;

C = find(cumsum(idx))

To get around the issue mentioned by Dennis in the comments:

m = min(A)-1;
A = A-m;
B = B-m;

idx = zeros(1,max(B)+1);
idx(A) = 1;
idx(B+1) = -1;

C = find(cumsum(idx)) + m;
+7
source

cumsum based approach for the general case (negative numbers or overlaps) -

%// Positions in intended output array at which group shifts
intv = cumsum([1 B-A+1])

%// Values to be put at those places with intention of doing cumsum at the end
put_vals = [A(1) A(2:end) - B(1:end-1)]

%// Get vector of ones and put_vals
id_arr = ones(1,intv(end)-1)
id_arr(intv(1:end-1)) = put_vals

%// Final output with cumsum of id_arr
out = cumsum(id_arr)

Run Example -

>> A,B
A =
    -2    -3     1
B =
     5    -1     3
>> out
out =
    -2    -1     0     1     2     3     4     5    -3    -2    -1     1     2     3

Benchmarking

warming-up tic-toc, , , A B -

%// Create inputs
A = round(linspace(1,400000000,200000));
B = round((A(1:end-1) + A(2:end))/2);
B = [B A(end)+B(1)];

disp('------------------ Divakar Method')
 .... Proposed approach in this solution

disp('------------------ Dan Method')
tic
idx = zeros(1,max(B)+1);
idx(A) = 1;
idx(B+1) = -1;
C = find(cumsum(idx));
toc, clear C idx

disp('------------------ Santhan Method')
tic
In = [A;B];
difIn = diff(In);
out1 = bsxfun(@plus, (0:max(difIn)).',A);            %//'
mask = bsxfun(@le, (1:max(difIn)+1).',difIn+1);     %//'
out1 = out1(mask).';  %//'
toc, clear out1 mask difIn In

disp('------------------ Itamar Method')
tic
C = cell2mat(cellfun(@(a,b){a:b},num2cell(A),num2cell(B)));
toc, clear C

disp('------------------ dlavila Method')
tic
C = cell2mat(arrayfun(@(a,b)a:b, A, B, 'UniformOutput', false));
toc

Runtimes

------------------ Divakar Method
Elapsed time is 0.793758 seconds.
------------------ Dan Method
Elapsed time is 2.640529 seconds.
------------------ Santhan Method
Elapsed time is 1.662889 seconds.
------------------ Itamar Method
Elapsed time is 2.524527 seconds.
------------------ dlavila Method
Elapsed time is 2.096454 seconds.
+5

Alternative option bsxfun

%// Find the difference between Inputs
difIn = B - A;

%// Do colon on A to A+max(difIn)
out = bsxfun(@plus, (0:max(difIn)).',A);            %//'

%// mask out which values you want
mask = bsxfun(@le, (1:max(difIn)+1).',difIn+1);     %//'

%// getting only the masked values
out = out(mask).'

Results:

>> A,B
A =
-2    -4     1

B =
 5    -3     3

>> out

out =

-2    -1     0     1     2     3     4     5    -4    -3     1     2     3
+4
source

This is one of the options:

C = cell2mat(cellfun(@(a,b){a:b},num2cell(A),num2cell(B)));
0
source

You can do it:

C = cell2mat(arrayfun(@(a,b)a:b, A, B, "UniformOutput", false))

arrayfun(...)create all subsequences that take pairs A and B. cell2matused to combine each subsequence.

0
source