Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an index vector based on start and stop values [duplicate]

Based on a matrix which contains several rows of the beginning (first column) and the end (second column) of an interval of index, I would like to create a vector of all the index. For instance, if A = [2 4; 8 11 ; 12 16], I would like to have the following vector index = [2 3 4 8 9 10 11 12 13 14 15 16].

I'm looking for the fastest way to do that. For now, I found only two possibilities:

1) with a loop

index = [];
for n = 1:size(A, 1)
    index = [index A(n, 1):A(n, 2)];
end

2) with arrayfun

index = cell2mat(arrayfun(@(n) A(n, 1):A(n, 2), 1:size(A, 1), 'uni', 0));

Interestingly, arrayfun is much faster than the loop version, and I don't know why. Plus I use a conversion from cell to mat, so that's weird. What do you think about that? Do you have another suggestions?

Thanx for your help

like image 588
andrew_077 Avatar asked Feb 17 '26 19:02

andrew_077


1 Answers

Hard to tell how fast that is, at least there is no looping:

A = [1,3;11,13;31,33;41,42;51,54;55,57;71,72];

%// prepare A
A = A.';

%// create index matrix
idx = bsxfun(@plus, A, [0; 1]);
%// special case: 54 and 55 are basically superfluous
%// need to be removed, but 71 and 72 shouldn't
A = A(:); 
dA = diff(A); dA(1:2:end) = 0;
idx = idx(~( [0;dA] == 1 | [dA;0] == 1 ));

%// create mask
mask = zeros(max(A),1);
mask(idx(:)) = (-1).^(0:numel(idx)-1);

%// index vector
out = find(cumsum(mask))

out.' =

      1  2  3 11 12 13 31 32 33 41 42 51 52 53 54 55 56 57 71 72
like image 105
Robert Seifert Avatar answered Feb 20 '26 22:02

Robert Seifert