Star
Star

Reputation: 2299

Vectorising a Matlab double loop involving 3D matrices?

Consider the following matrices in Matlab

A(:,:,1)=[1 2 3; 4 5 6];
A(:,:,2)=[7 8 9; 10 11 12];
M=size(A,1);
N=size(A,2);
R=size(A,3);

I want to create a matrix B of dimension (M*N)x(N-1)xR such that

-for each r=1,...,R,

-for each m=1,...,M

-for each h=1,...,N

-I take A(m,h,r), sum it with each of the N-1 remaining elements in A(m,:,r), and fill B((m-1)*N+h,:,r).

In the example above it should be

B(:,:,1)=[1+2 1+3;
          2+1 2+3;
          3+1 3+2;
          4+5 4+6;
          5+4 5+6;
          6+4 6+5]

B(:,:,2)=[7+8 7+9;
          8+7 8+9;
          9+7 9+8;
          10+11 10+12;
          11+10 11+12;
          12+10 12+11]

This code does what I want but it contains a double loop, which for M,N large may be slow. Could you help me to vectorize?

for m=1:M
    for h=1:N
        B((m-1)*N+h,:,:)= repmat(A(m,h,:),1,N-1)+[A(m,1:h-1,:) A(m,h+1:N,:)]; 
    end
end

Upvotes: 1

Views: 45

Answers (1)

gnovice
gnovice

Reputation: 125854

I'm not sure how much more efficient it will be, but you could reduce it to a single loop like so:

[M, N, R] = size(A);
B = zeros(M*N, N-1, R);
for index = logical(eye(N))
  B(find(index):N:end, :, :) = bsxfun(@plus, A(:, ~index, :), A(:, index, :));
end

Upvotes: 1

Related Questions