Sternpost_0122
Sternpost_0122

Reputation: 21

Matlab for loop replacement

I am trying to reduce the amount of loops in my code to speed up computation. I have encountered a portion of code I am completing with a loop which I cannot see a solution.

I have a matrix of x y coords of various particles. For example, generated as rand(2,5)

0.8715    0.0363    0.0657    0.6289    0.3279
0.0272    0.4380    0.9794    0.6563    0.4755

I would like a matrix in (5,5,2) with a vector between each particle. This would be a matrix of x lengths as (:,:,1) and y lengths as (:,:,2).

Upvotes: 2

Views: 929

Answers (2)

gnovice
gnovice

Reputation: 125854

Here's an indexing-based solution that uses REPMAT to create the linear index into the coordinate matrix and CAT to create the 3-D matrix result:

>> xy = [0.8715  0.0363  0.0657  0.6289  0.3279; ...  %# Your coordinates
         0.0272  0.4380  0.9794  0.6563  0.4755];
>> N = size(xy, 2);
>> index = repmat(1:2:2*N, N, 1);  %# A matrix of linear indices into xy
>> result = cat(3, xy(index)-xy(index.'), ...  %.'# X differences
                xy(index+1)-xy(index.'+1))     %.'# Y differences

result(:,:,1) =

         0   -0.8352   -0.8058   -0.2426   -0.5436
    0.8352         0    0.0294    0.5926    0.2916
    0.8058   -0.0294         0    0.5632    0.2622
    0.2426   -0.5926   -0.5632         0   -0.3010
    0.5436   -0.2916   -0.2622    0.3010         0

result(:,:,2) =

         0    0.4108    0.9522    0.6291    0.4483
   -0.4108         0    0.5414    0.2183    0.0375
   -0.9522   -0.5414         0   -0.3231   -0.5039
   -0.6291   -0.2183    0.3231         0   -0.1808
   -0.4483   -0.0375    0.5039    0.1808         0

Upvotes: 0

Jonas
Jonas

Reputation: 74930

You can use bsxfun for this, though you'll also need permute to "3D-transpose" the coordinate matrix. permute turns coordinates into a 5-by-1-by-2, and a 1-by-5-by-2 array, respectively:

coordinates = rand(2,5);

%# subtract all coordinate pairs from one another
vectorArray = bsxfun(@minus,permute(coordinates,[2,3,1]),permute(coordinates,[3 2 1]));

size(vectorArray)
ans =
     5     5     2

Note that the vectorArray is antisymmetric, so you may want to look into pdist if you run into space problems.

Upvotes: 2

Related Questions