2017-11-12 19 views
3

私は6 * n * n * 3行と6 * n * n点の3次元座標を表す1つの列を持つmatlabの行列xを持っています。座標は、行1:6 * n * nがx座標であり、行6 * n * n + 1:12 * n * nがy座標であり、12 * n * n + 1:18 * n * nはz座標である。matlabの行列を再構成する

与えられた点のx、y、z座標を単に置き、もう一方の行iが他のすべての点に点iを減算することで構成される2つの新しい行列を作成したいと思います。

今は、n> 16で非常に遅いdouble forループを使用しています。 matlabのベクトル/行列の機能を使ってこれを行うより良い/より速い方法がありますか?

ここでは、私はあなたのデータがどのように見えるかのアイデアを持っていますが、のは簡単な事で試してみて、私は最終的に私の答えを拡張しますせてはいけない私の現在のコード

x=x(1:6*n*n); 
y=y(6*n*n+1:12*n*n); 
z=z(12*n*n+1:18*n*n); 
N=6*n*n; 
points=[]; 
difs=[]; 
for i=1:N 
    difrow=[]; 
    points=[points;x(i) y(i) z(i)]; 
    for j=1:N 
     deltax=x(i)-x(j); 
     deltay=y(i)-y(j); 
     deltaz=z(i)-z(j); 
     difrow=[difrow deltax deltay deltaz]; 
    end 

    difs=[difs;difrow]; 
end 

答えて

4

あなたは(x ,y,zサイズ[N x 1]の列ベクトルであると仮定)配列が再形成及び連結、bsxfunを使用してループを回避することができます

points = [x y z]; 
deltax = bsxfun(@minus,x.' , x); 
deltay = bsxfun(@minus,y.' , y); 
deltaz = bsxfun(@minus,z.' , z); 
difs = reshape([deltax(:) deltay(:) deltaz(:)].',N*3,[]).'; 

それとも、あなたが行うことができますMATLABの最近のバージョンで:

points = [x y z]; 
deltax = x.' - x; 
deltay = y.' - y; 
deltaz = z.' - z; 
difs = reshape([deltax(:) deltay(:) deltaz(:)].',N*3,[]).'; 
+0

点は、N行(各点に1つ)と3つの列(各点座標に1つ)の行列である必要があります。上記のコードは、1行と3 * N列のポイント行列を与えます。 – JennyToy

+0

私は参照してください。いいえx、y、zはそれぞれN長の行です。 – JennyToy

+0

OKサイズは '[1 x N]' – rahnema1

1

です。

最初のマイクロ最適化:は、ループ時にパフォーマンスを向上させるために、常に中間結果をMatlabにキャッシュします。

x = x(1:6*n*n); 
y = y(6*n*n+1:12*n*n); 
z = z(12*n*n+1:18*n*n); 

points = []; 
difs = []; 

for i=1:N 
    difrow = []; 

    x_i = x(i); 
    y_i = y(i); 
    z_i = z(i); 

    points = [points; x_i y_i z_i]; 

    for j=1:N 
     deltax = x_i - x(j); 
     deltay = y_i - y(j); 
     deltaz = z_i - z(j); 

     difrow = [difrow deltax deltay deltaz]; 
    end 

    difs=[difs; difrow]; 
end 

第2のマイクロ最適化:インライン・メモリの再割り当てを避けるために、あなたの配列を事前にインスタンス化します。

x = x(1:6*n*n); 
y = y(6*n*n+1:12*n*n); 
z = z(12*n*n+1:18*n*n); 

points = NaN(N,1); 
difs = []; 

for i=1:N 
    x_i = x(i); 
    y_i = y(i); 
    z_i = z(i); 

    points(i) = [x_i y_i z_i]; 

    difrow = NaN(N,1); 

    for j=1:N 
     deltax = x_i - x(j); 
     deltay = y_i - y(j); 
     deltaz = z_i - z(j); 

     difrow(j) = [deltax deltay deltaz]; 
    end 

    difs = [difs; difrow]; 
end 
+0

これを実行しましたか?それは少し改善しますが、n = 20の場合は2400ポイントで4分かかり、n = 36にする必要があります。 – JennyToy

+0

4分はそれほど長くはありませんが、何をしようとしているのか、どのように見えているのかわからないので、同じコードを得るために全く新しいロジックを開発するのは難しいですパフォーマンスが向上します。 –