2011-06-16 71 views
3

我正在爲學校編寫一個程序,我嵌套for-loops創建一個4維數組(座標爲(x,y)和(x 'Y')),如下:在Matlab中矢量化4個嵌套for-loops

pos_x=1:20; 
pos_y=1:20; 
Lx = length(pos_x);    
Ly = length(pos_y); 
Lx2 = Lx/2; 
Ly2 = Ly/2; 

%Distance function, periodic boundary conditions 
d_x=abs(repmat(1:Lx,Lx,1)-repmat((1:Lx)',1,Lx)); 
d_x(d_x>Lx2)=Lx-d_x(d_x>Lx2); 
d_y=abs(repmat(1:Ly,Ly,1)-repmat((1:Ly)',1,Ly)); 
d_y(d_y>Ly2)=Ly-d_y(d_y>Ly2); 

for l=1:Ly 
    for k=1:Lx 
     for j=1:Ly 
      for i=1:Lx 
      distance(l,k,j,i)=sqrt(d_x(k,i).^2+d_y(l,j).^2); 
      end 
     end 
    end 
end 

D_X和d_y只是20×20的矩陣和LX = Ly的審判的目的。這很慢,顯然不是一個非常優雅的做法。我試圖向量化嵌套循環和成功地擺脫所述兩個內部循環爲:

dx2=zeros(Ly,Lx,Ly,Lx); 
dy2=zeros(Ly,Lx,Ly,Lx); 
distance=zeros(Ly,Lx,Ly,Lx); 

for l=1:Ly 
    for k=1:Lx 
     dy2(l,k,:,:)=repmat(d_y(l,:),Ly,1); 
     dx2(l,k,:,:)=repmat(d_x(k,:)',1,Lx); 
    end 
end 
distance=sqrt(dx2.^2+dy2.^2); 

基本上取代了4上方for循環。我現在已經嘗試了2天,但我找不到一種向量化所有循環的方法。我想問:

  1. 是否有可能真正擺脫這兩個循環的
  2. 如果是的話,我會很感激任何提示和技巧來做到這一點。 我到目前爲止仍嘗試在4維中再次使用repmat,但是您不能轉置4維矩陣,所以我嘗試在許多不同組合中一起使用置換和repmat無效。

任何意見將不勝感激。


感謝您的回覆。對不起的措辭,我基本上想要的是有一個振盪器的人口統一位於X - Y平面。我想模擬它們的耦合,耦合函數是每個振盪器之間距離的函數。每個振盪器都有x和y座標,所以我需要找到osci(1,1)osci(1,1),..osci(1,N),osci(2,1),..osci(N,N)...之間的距離,然後osci(1,2)osci(1,1)...osci(N,N)等等(基本上所有振盪器和所有其他振盪器之間的距離,耦合)如果有一種更簡單的方法來做到這一點,除了使用4-D陣列,我也絕對想知道它..

+4

你說你想要兩個座標之間的距離。不應該給你一個2D數組,其中'(i,j)'是'[x1i,y1i]'和'[x2i,y2i]'之間的距離? – Jonas 2011-06-16 18:09:56

+1

我第二個喬納斯的評論。你能解釋計算[x1i,y2j]和[x1k,y2l]之間距離的理由嗎?如果你提供一個理由,可能有一個快捷方式來獲得這個答案,沒有填充4D矩陣。 – BlessedKey 2011-06-16 18:33:57

+1

我還沒有讀過你的代碼,但我有一個預感它類似於[這個問題](http:// stackoverflow。COM /問題/ 5768136 /優化-MATLAB的代碼嵌套for循環到計算相似性矩陣/ 5768224#5768224)。你可能想嘗試看看那裏的答案,看看它是否有幫助。 – abcd 2011-06-16 23:07:45

回答

1

如果我正確地理解你,你有振盪器到處都是,就像這樣:

enter image description here

然後你要計算振盪器1和振盪器之間的距離1到100,然後在振盪器2和振盪器1到100之間等等。我相信這可以用2D距離矩陣表示,第一維從1到100,第二維從1到100.

例如

%# create 100 evenly spaced oscillators 
[xOscillator,yOscillator] = ndgrid(1:10,1:10); 
oscillatorXY = [xOscillator(:),yOscillator(:)]; 

%# calculate the euclidean distance between the oscillators 
xDistance = abs(bsxfun(@minus,oscillatorXY(:,1),oscillatorXY(:,1)')); %'# abs distance x 
xDistance(xDistance>5) = 10-xDistance; %# add periodic boundary conditions 
yDistance = abs(bsxfun(@minus,oscillatorXY(:,2),oscillatorXY(:,2)')); %'# abs distance y 
yDistance(yDistance>5) = 10-yDistance; %# add periodic boundary conditions 

%# and we get the Euclidean distance 
euclideanDistance = sqrt(xDistance.^2 + yDistance.^2); 
0

我發現虛數有時可以幫助傳達再加信息相當不錯,同時減少混亂。我的方法將必要的計算數量增加一倍(即我找到距離X和Y,然後Y和X),我仍然需要循環單

x = 1:20; 
y = 1:20; 
[X,Y] = meshgrid(x,y); 
Z =X + Y*i; 
z = Z(:); 
leng = length(z); 
store = zeros(leng); 
for looper = 1:(leng-1) 
    dummyz = circshift(z,looper); 
    store(:,looper+1) = z - dummyz; 
end 
final = abs(store);