2

ここに同様の質問がありますElement-wise array replication in Matlabですが、少し一般化したいと思います。単純なケースでは、ベクトル a を取り、各要素を数値 NEg で複製する関数 'replicate' が必要です。

>> a = [1, 2, 3];
>> replicate(a, 3);
ans = 
  [1, 1, 1, 2, 2, 2, 3, 3, 3]
>>

上記のリンクには、役立つ解決策がいくつかあります。しかし、N が各要素の多重度のベクトルである場合はどうなるでしょうか。たとえば、次のようなものが欲しいです:

>> a = [1, 2, 3];
>> N = [3, 1, 5];
>> replicate(a,N)
ans = 
  [1, 1, 1, 2, 3, 3, 3, 3, 3]
>>

残念ながら、私の MATLAB-index-fu はこのレベルに達していません。たとえば、N をループし、repmat を使用して a の各要素をサイズ [N (i),1] ベクトル。たとえば、配列データをループし、multcol 位置の多重度値を使用して remat します。データは MCMC のステップであり、各ステップの多重度は最後の列にあります。

data=[-3.997 4.402 0.000 703.050 -219.900 289.600 2.000 5.700 -49.100 11.100 3;...
-2.476 2.685 0.000 667.800 -220.210 290.000 1.955 5.710 -48.828 11.116 3; ...
-4.658 0.286 0.000 626.370 -220.420 290.380 2.019 5.991 -49.015 11.1210 2];

multcol = 11;

%unwrap the data
in=1;
for i=1:size(data,1)
  data_uw(in:in+data(i,multcol)-1,:) = ...
    repmat(data(i,1:multcol-1),[data(i,multcol) 1]);
  in=in+data(i,multcol);
end

これは機能しますが、比較的遅いです。最終結果 data_uw は、入力行列 data の各行であり、多重度列の回数だけ複製されます。

>> data_uw

data_uw =

Columns 1 through 7

-3.9970    4.4020         0  703.0500 -219.9000  289.6000    2.0000
-3.9970    4.4020         0  703.0500 -219.9000  289.6000    2.0000
-3.9970    4.4020         0  703.0500 -219.9000  289.6000    2.0000
-2.4760    2.6850         0  667.8000 -220.2100  290.0000    1.9550
-2.4760    2.6850         0  667.8000 -220.2100  290.0000    1.9550
-2.4760    2.6850         0  667.8000 -220.2100  290.0000    1.9550
-4.6580    0.2860         0  626.3700 -220.4200  290.3800    2.0190
-4.6580    0.2860         0  626.3700 -220.4200  290.3800    2.0190

Columns 8 through 10

  5.7000  -49.1000   11.1000
  5.7000  -49.1000   11.1000
  5.7000  -49.1000   11.1000
  5.7100  -48.8280   11.1160
  5.7100  -48.8280   11.1160
  5.7100  -48.8280   11.1160
  5.9910  -49.0150   11.1210
  5.9910  -49.0150   11.1210

これを行うより良い方法はありますか?上のリンクの答えを適応させる方法があるかもしれませんが、私はそれを得ていません。

回答で更新

http://www.mathworks.co.uk/matlabcentral/fileexchange/6436-rude-a-pedestrian-run-length-decoder-encoderで利用可能なユーティリティ rude を使用しました。

mult = data(:,multcol);
data = data(:,1:multcol-1);
iterations = sum(mult);

%preallocate the unwrapped data vector for speed
data_uw = zeros(iterations,multcol-1);
nstep = size(data,1);
ind = 1:nstep;
ind_uw = zeros(iterations,1);
ind_uw = rude(mult,ind);
data_uw = data(ind_uw,:);

これははるかに高速に思えます。Rude は、別の回答で言及されている cumsum テクニックを利用しているため、それも機能します。

4

3 に答える 3

2

アルゴリズムはランレングス デコードであり、rube()を使用することをお勧めします。これはマイルストーンであり、非常によく書かれた MATLAB コードです。

>> rude(N,a)
ans =
     1     1     1     2     3     3     3     3     3

ただし、あなたの場合、問題は事前割り当てにあるはずです(欠落しています)。コードの事前割り当てとリファクタリング:

% Pre-allocate
out = zeros(sum(data(:,end)),multcol-1);

for i = 1:size(data,1)
    n = data(i,multcol);
    out(in : in+n-1,:) = repmat(data(i,1:end-1),n,1);
    in = in+n;
end
于 2013-04-11T23:28:54.790 に答える
0

この種のものには、cumsum ベースのインデックス作成を使用できます。

A = [4 5 6];
N = [3 1 5];

cs=cumsum(N);
idx = zeros(1,cs(end));
idx(1+[0 cs(1:end-1)]) = 1; #%[1 0 0 1 1 0 0 0 0]
idx = cumsum(idx); #%[1 1 1 2 3 3 3 3 3]

B = A(idx); #%[4 4 4 5 6 6 6 6 6]
于 2013-04-11T23:54:01.540 に答える