repeating elements of a vector

1 view (last 30 days)
Rabeya
Rabeya on 16 May 2012
I have two vectors, say lambda=[1; 2] and ng=[3;4]. I want to have a long vector where the elements of lambda are repeated the corresponding times of the values of ng, i.e., I want to get
lambda_long=[1;1;1;2;2;2;2]
I can do it with some for loop, but is there any other efficient way of doing this?

Accepted Answer

Oleg Komarov
Oleg Komarov on 16 May 2012
Fully vectorized run-length decoding:
% Example inputs (as vector columns)
lambda = [2; 4;9];
ng = [3;4;7];
% Preallocate output
out = zeros(sum(ng),1);
% Distribute starting point of sequences
csng = cumsum(ng);
out([1; csng(1:end-1)+1]) = [lambda(1); diff(lambda)];
% Propagate
out = cumsum(out)

More Answers (3)

Andrei Bobrov
Andrei Bobrov on 16 May 2012
x = arrayfun(@(a,b)a(ones(b,1)),lambda,ng,'un',0)
lambda_long = cat(1,x{:})
add
eg:
lambda = [14 5 89 47]'
ng=[3 4 2 4]'
% solution
id = zeros(sum(ng),1);
id(cumsum(ng)-ng+1)=1;
lambda_long = lambda(cumsum(id));

Jan
Jan on 16 May 2012
Similar to Oleg's encoding, but avoid DIFF/CUMSUM of data to prevent rounding errors:
lambda = [2; 4; 9];
ng = [3; 4; 7];
index(cumsum(ng)+1) = 1;
index(1) = 1;
index(end) = [];
out = lambda(cumsum(index));
Untested!

Wayne King
Wayne King on 16 May 2012
One way
lambda=[1; 2];
ng=[3;4];
A = repmat(lambda(1),ng(1),1);
B = repmat(lambda(2),ng(2),1);
C = [A;B];
Of course, you could put this on one line.
C = [repmat(lambda(1),ng(1),1); repmat(lambda(2),ng(2),1)];
  1 Comment
Rabeya
Rabeya on 16 May 2012
this is fine for such low length lambda, but not when you have 50 values for lambda!

Sign in to comment.

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!