Reputation: 21
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
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
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