2016-09-11 3 views
0

ロードするデータをフォーマットするために使用されるネストされたfor-loopsが2つあります。私は彼らの所望のサイズに事前に割り当てないMATLABで2つのネストされたfor-loopsをベクトル化します

data = magic(20000); 
data = data(:,1:3); 

for i=0:10 
    for j=0:10 
     data_tmp = data((1:100)+100*j+100*10*i,:); 
     vx(:, i+1,j+1) = data_tmp(:,1); 
     vy(:, i+1,j+1) = data_tmp(:,2); 
     vz(:, i+1,j+1) = data_tmp(:,3); 
    end 
end 

配列vxvyvz:ループは次のような構成を持っています。しかし、効率を高めるためにループをベクトル化する方法がありますか?私はそれが第二のループの最初の行、data((1:100)+100*j+100*10*i,:)のためのケースであると確信していない、これを行うには良い方法はありますか?それはあなたが例えばk<10

ためi=k, j=10i=k+1, j=0でループ

にインデックスを繰り返していることが判明し

答えて

2

、あなたは1:100 + 100*10 + 100*10*0を読み、その後、同一の1:100 + 100*0 + 100*10*1をお読みください。 /繰り返しインデックス

ワット

形状変更、これはあなたがすることを意図したものだった場合は、ベクトル化が一歩(インデックス生成)が必要です。続き

は(Ndata_tmpMの長さであるN=100, M=10最大ループ変数がある)私の提案

index = bsxfun(@plus,bsxfun(@plus,(1:N)',reshape(N*(0:M),1,1,M+1)),M*N*(0:M)); %index generation 
vx = data(index); 
vy = data(index + size(data,1)); 
vz = data(index + size(data,1)*2); 

これは、その望ましいことではないですが、それは動作します。

ラップトップでテストしたところ、事前割り当てで元のコードよりも2倍高速でした。私はデータのサイズを大きくすると、ギャップは小さくなります。

リシェープW/O繰り返しインデックス

つまり、あなたが最初の第3次元の方向に各列を再構築したくない場合は、第二の次元の最後)、次は動作します。

まず、これは私がそのループが(M-1)で終了

data = magic(20000); 
data = data(:,1:3); 

N = 100; M = 10; 
for i=0:(M-1) 
    for j=0:(M-1) 
     data_tmp = data((1:N)+M*j+N*M*i,:); 
     vx(:, i+1,j+1) = data_tmp(:,1); 
     vy(:, i+1,j+1) = data_tmp(:,2); 
     vz(:, i+1,j+1) = data_tmp(:,3); 
    end 
end 

注意してコードを解釈する方法です。

私の提案は次のとおりです。

vx = permute(reshape(dat(1:N*M*M,1), N, M, M),[1,3,2]); 
vy = permute(reshape(dat(1:N*M*M,2), N, M, M),[1,3,2]); 
vz = permute(reshape(dat(1:N*M*M,3), N, M, M),[1,3,2]); 

私のラップトップでは、元のコードより4倍高速です。私はサイズを大きくしたように、ギャップは、あなたがループに固執したいだけの場合には2

+0

これは素晴らしい提案です。ありがとうございます!非常に役立ちます – BillyJean

1

に近づき、ここではこれを行うにははるかに高速な方法である:

data = randi(100,20000,3); 
[vx,vy,vz] = deal(zeros(100,11,11)); 
[J,I] = ndgrid(1:11,1:11); 
c = 1; 
for k = 0:100:11000 
    vx(:,I(c),J(c)) = data((1:100)+k,1); 
    vy(:,I(c),J(c)) = data((1:100)+k,2); 
    vz(:,I(c),J(c)) = data((1:100)+k,3); 
    c = c+1; 
end 

私の推測では、からのreshapeです@Dohyunの答えはあなたが探しているものです(これより10倍速く、あなたのコードよりもx10000速い)が、次回はループを使うために便利かもしれません。


そしてここreshapeバージョンと同様の時間で、reshapeせずにこれを行うには別のオプションです:

[vx,vy,vz] = deal(zeros(100,10,11)); 
vx(:) = data(1:11000,1); 
vy(:) = data(1:11000,2); 
vz(:) = data(1:11000,3); 
vx = permute(vx,[1 3 2]); 
vy = permute(vy,[1 3 2]); 
vz = permute(vz,[1 3 2]); 

アイデアそれらを割り当て中にあなたが[vx,vy,vz]の形状を定義することです。

関連する問題