Repeating a vector up to a given length

24 ビュー (過去 30 日間)
Adam
Adam 2016 年 11 月 21 日
編集済み: Adam 2016 年 11 月 23 日
This is one of those case where I feel there has to be a neater way to do what seems like a very simple operation, but I can't think of it.
I want to extend a vector up to some new size by repeating that vector (or some part of the vector starting at the beginning for the final incomplete repitition). Now this gives me the correct result:
traceData = rand(277,1);
len = 4096;
extendedTraceData = repmat( traceData, ceil( len / numel( traceData ) ), 1 );
extendedTraceData = extendedTraceData( 1:len );
but it looks a bit ugly. Am I missing some 1 line function that can do this since repmat only allows full replications of a vector rather than partial ones.

採用された回答

Jan
Jan 2016 年 11 月 21 日
編集済み: Jan 2016 年 11 月 21 日
X = rand(277,1);
len = 4096;
extendedX = [repmat(X, floor(len / numel(X)), 1); ...
X(1:mod(len, numel(X)))];
Or:
extendedX = X(mod(0:len-1, numel(X)) + 1);
  4 件のコメント
Jan
Jan 2016 年 11 月 22 日
編集済み: Jan 2016 年 11 月 22 日
But note, that the 2nd answer creates a long temporary vector, which is used for indexing. This means that each elemt is checked if it is inside the boundaries and this wastes a lot of time.
Therefore the first method should be faster. But even here the two parts will be created as temporary arrays at first.
Adam
Adam 2016 年 11 月 23 日
編集済み: Adam 2016 年 11 月 23 日
Yes, A quick analysis with timeit does show the 2nd answer to be slower and more sensitive to length too, getting progressively slower. Actually my original solution appears to be slightly the fastest, but speed is not really a factor in my usage anyway.
Obviously what I originally had works fine, but I'm always interested to keep learning so even when it is just an academic exercise of interest I like to see see alternative methods to solve the same problem.
Sometimes speed is most important, sometimes I just want less ugly code and sometimes I just want to have looked at the different alternatives to learn!
For interest, here is a plot of my quick analysis of the 3 approaches for lengths 295, 512, 1024, 2048, 16384, 524288

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

その他の回答 (2 件)

Guillaume
Guillaume 2016 年 11 月 21 日
編集済み: Guillaume 2016 年 11 月 21 日
Unless there's something hidden in some toolbox, I don't think that there is any matlab function to do that in just one line. Replicate and crop as you've done looks like the most efficient solution.
... until matlab supports indexing the return value of a function.

Image Analyst
Image Analyst 2016 年 11 月 21 日
Regarding "or some part of the vector starting at the beginning".........To replicate just the beginning portion of your vector, use colon. For example to replicate only the first 100 elements of the 277, do this:
extendedTraceData = repmat(traceData(1:100),......
  1 件のコメント
Adam
Adam 2016 年 11 月 21 日
Well, I want to replicate the full vector, but the final replication will generally not be a full replication because e.g. my start vector is length 3 and I want a length 8 result so I would have 2 full repetitions of my vector and then just the first two elements for the final repetition.

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

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by