2011-06-16 68 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);