2017-01-31 14 views
2

は、私はこのようなベクターを持っている:ベクトルの3番目の要素をどのように繰り返すか?

h = [1,2,3,4,5,6,7,8,9,10,11,12] 

をそして私はそうのように、すべての第三の要素を繰り返したい:

h_rep = [1,2,3,3,4,5,6,6,7,8,9,9,10,11,12,12] 

がどのように私はMATLABでエレガントにこれを実現するのですか?実際の配列は巨大なので、理想的には私はforループを書こうとしません。これを行うベクター化された方法はありますか?

+1

私たちの答えのいずれかが助けていましたか? – rayryeng

+0

ここでの解決策のタイミングは面白いかもしれません... – gnovice

+1

@gnovice今夜はすべてのソリューションに時間を掛けて、投稿を編集します。アイデアありがとう!ところで、私はルイスのソリューションが最速になると思う...彼はインデックス作成だけを使用する。 – rayryeng

答えて

6

これを行う1つの方法は、ベクトルR2015bでリリースされた最近のrepelem関数を使用して、ベクトルの各要素を一定の回数繰り返すことです。あなたの例を使用し

N = numel(h); 
rep = ones(1, N); 
rep(3:3:end) = 2; 
h_rep = repelem(h, rep); 

:この場合には、すべての第三の要素は、関数を使用し、その後、対応する要素を繰り返す回数として1である値の残りと2であるベクトルを指定します。 h = 1 : 12、我々はこのように得る:

>> h_rep 

h_rep = 

    1  2  3  3  4  5  6  6  7  8  9  9 10 11 12 12 

repelemはあなたに利用できない場合、cumsumの巧妙な使用が役立つかもしれません。基本的に、3つの要素ごとに、次の要素は前の要素のコピーです。 [1 1 1 0]の指標ベクトルがある場合は、1はコピーしたい位置です。0は、このベクトルの繰り返しバージョンで累積合計またはcumsumを使用して最終値をコピーするように指示しています。正確に1 + (numel(h)/4)は、 hにインデックスするしたがって、hの長さはすべての4番目の要素がcumsumを適用する前に0に設定されていることを確認した後、我々は重複要素のためのスペースを作ることを保証するために1 + (numel(h)/4が付加されているもののベクトルを作成します。

N = numel(h); 
rep = ones(1, N + 1 + (N/4)); 
rep(4:4:end) = 0; 
rep = cumsum(rep); 
h_rep = h(rep); 

したがって:

>> h_rep 

h_rep = 

    1  2  3  3  4  5  6  6  7  8  9  9 10 11 12 12 

つ最後の提案(ユーザ@bremen_mattのおかげで)、それは3行を有することが、単一のベクターに戻し、得られた複製行列を再形成、最後の行を複製するので、あなたのベクトルを行列にreshapeになるであろう。

h_rep = reshape(h, 3, []); 
h_rep = reshape([h_rep; h_rep(end,:)], 1, []); 

我々は再び取得:もちろん

>> h_rep 

h_rep = 

    1  2  3  3  4  5  6  6  7  8  9  9 10 11 12 12 

上記のコードとの明白な注意点は、ベクトルhの長さが、私はこの意志を考える4.

1

で割り切れるということですする:

h = [1,2,3,4,5,6,7,8,9,10,11,12]; 
h0=kron(h,[1 1]) 
h_rep=h0(mod(1:length(h0),2)==0 | mod(1:length(h0),3)==2) 

回答:

1  2  3  3  4  5  6  6  7  8  9  9 10 11 12 12 

説明: すべての要素を複製した後、あなたはあなたが望んでいるものを選択します。この考え方を2番目と3番目に重複するように拡張することができます。等..

+2

*すべての*要素をコピーして不要な要素を削除することの欠点は、計算上およびメモリ上のオーバーヘッドです。 – Adriaan

6

(rayryengの正しい所見に応じて変更)...

別の解決策は、関数reshapeで遊ぶことです。あなたが最初の3XN行列に行列を作り変える場合は...その後、

B = reshape(h,3,[]) 

とすることができます

B = [B;B(end,:)] 

そして最後にソリューションをベクトル化...

B(:).' 
+0

コメントのいくつか:(1) 'reshape'の最後の引数に' numel(h)/ 3'の代わりに '[]'を指定すると、必要なカラム数を自動的に計算できます。 (2)OPは行ベクトルを必要とするかもしれないので、完了後に 'B(:)'を転置してください。 – rayryeng

4

最後の行をコピーインデックスのみを使用:

h = [1,2,3,4,5,6,7,8,9,10,11,12]; % initial data 
n = 3; % step for repetition 
h_rep = h(ceil(n/(n+1):n/(n+1):end)); 
3

sortを使用して)インデックスベースのアプローチ:

h_rep = h(sort([1:numel(h) 3:3:numel(h)])); 

またはわずかに短い構文が...

h_rep = h(sort([1:end 3:3:end])); 
+0

'sort'を使った興味深いアプローチ! – rayryeng

関連する問題