在Matlab中矢量化4个嵌套的for循环

时间:2011-06-16 17:00:15

标签: matlab nested-loops

我正在为学校编写一个程序,我已经嵌套了for循环,创建了一个4维数组(两个点之间的距离,坐标为(x,y)和(x',y')),如下所示:

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仅为20x20矩阵,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维矩阵,所以我尝试使用permute和repmat在许多不同的组合中无济于事。
  3. 非常感谢任何建议。


    感谢回复。对不好的措辞感到抱歉,我基本上想要的是让一群振荡器均匀地位于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阵列之外还有更简单的方法,我也非常想知道它......

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

我发现虚数有时可以帮助传达耦合信息,同时减少混乱。我的方法将使所需的计算次数加倍(即我找到距离X和Y,然后是Y和X),我仍然需要一个for循环

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);