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?

 採用された回答

Oleg Komarov
Oleg Komarov 2012 年 5 月 16 日

1 投票

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)

その他の回答 (3 件)

Andrei Bobrov
Andrei Bobrov 2012 年 5 月 16 日

3 投票

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));

1 件のコメント

Rabeya
Rabeya 2012 年 5 月 16 日
This is clever too. Thanks!

サインインしてコメントする。

Jan
Jan 2012 年 5 月 16 日

1 投票

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 2012 年 5 月 16 日

0 投票

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 件のコメント

Rabeya
Rabeya 2012 年 5 月 16 日
this is fine for such low length lambda, but not when you have 50 values for lambda!

サインインしてコメントする。

カテゴリ

ヘルプ センター および File Exchange で Loops and Conditional Statements についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by