フィルターのクリア

Efficient way to split a vector into Matrix

3 ビュー (過去 30 日間)
RoJo
RoJo 2011 年 4 月 14 日
Hi,
I am looking for an efficient way to do the following:
Take an input vector, e.g B = [2;5;8;11;3;6;9;15]
and return the array
D = [2 5 8 11 3;5 8 11 3 6;8 11 3 6 9]
, ie each column is a rolling subvector of B
My attempt below works but it causes a bottleneck in my programme. I have been trying to vectorize it but am finding it difficult.
If somebody has thoughts I would appreciate a pointer.
Thanks!
function ret = MakeMatrix(inputVector, inputLookbackPeriod, numPeriodsToCalculate)
m_Array = zeros(inputLookbackPeriod, numPeriodsToCalculate);
for i=1:numPeriodsToCalculate
m_Array(:,i) = inputVector(i:i+inputLookbackPeriod-1,1);
end
end

採用された回答

the cyclist
the cyclist 2011 年 4 月 14 日
Here is an obscure way, using a Hilbert matrix. It is semi-coincidental that the indexing you need is exactly the (element-by-element inverse of the) Hilbert matrix.
For something less esoteric, you could probably use the filter command.
function m_Array = MakeMatrixFast(inputVector, inputLookbackPeriod, numPeriodsToCalculate)
H = 1./hilb(max(inputLookbackPeriod,numPeriodsToCalculate));
H = H(1:inputLookbackPeriod,1:numPeriodsToCalculate);
m_Array = inputVector(H);
end
  2 件のコメント
RoJo
RoJo 2011 年 4 月 14 日
Thanks. This does what I was asking. One point is that as I increase the argument to hilb, e.g 1./hilb(30) the resulting matrix contains 49.000.. which fails inputVector(H). So just needs a conversion before that line.
the cyclist
the cyclist 2011 年 4 月 14 日
Yeah, I should have anticipated that. Can you just put in a rounding command?

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

その他の回答 (2 件)

Andrei Bobrov
Andrei Bobrov 2011 年 4 月 14 日
variant
D0 = buffer(B,5,4);
D = D0(2:end-1,4:end)
  2 件のコメント
RoJo
RoJo 2011 年 4 月 14 日
Thanks for the reply. I don't have the Signal Processing Toolbox to use the buffer function however.
Teja Muppirala
Teja Muppirala 2011 年 4 月 14 日
You learn something new every day...

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


Matt Fig
Matt Fig 2011 年 4 月 14 日
IDX = ones(3,5,'single');
IDX(:,1) = 1:3;
D = B(cumsum(IDX,2))
Or, to match your functional form:
function m_Array = MakeMatrixFast2(inputVector, inputLookbackPeriod, numPeriodsToCalculate)
IDX = ones(inputLookbackPeriod,numPeriodsToCalculate,'single');
IDX(:,1) = 1:inputLookbackPeriod;
m_Array = inputVector(cumsum(IDX,2));
  2 件のコメント
RoJo
RoJo 2011 年 4 月 14 日
Sorry, I didn't refresh the page and see this answer. It works well and is efficient for large/small vectors and lookbacks. Thanks.
Matt Fig
Matt Fig 2011 年 4 月 14 日
That's o.k.! I tested all three algorithms and yours is actually faster than the cyclist's. Mine is somewhat faster than yours for certain inputs.

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

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by