1

I am trying to optimize my code and am not sure how and if I would be able to vectorize this particular section??

for base_num = 1:base_length
    for sub_num = 1:base_length
    dist{base_num}(sub_num) = sqrt((x(base_num) - x(sub_num))^2 + (y(base_num) - y(sub_num))^2);
    end
end
Colin T Bowers
  • 18,106
  • 8
  • 61
  • 89
user1878019
  • 65
  • 1
  • 6

1 Answers1

1

The following example provides one method of vectorization:

%# Set example parameters
N = 10;
X = randn(N, 1);
Y = randn(N, 1);

%# Your loop based solution
Dist1 = cell(N, 1);    
for n = 1:N
    for m = 1:N
        Dist1{n}(m) = sqrt((X(n) - X(m))^2 + (Y(n) - Y(m))^2);
    end
end

%# My vectorized solution
Dist2 = sqrt(bsxfun(@minus, X, X').^2 + bsxfun(@minus, Y, Y').^2);
Dist2Cell = num2cell(Dist2, 2);

A quick speed test at N = 1000 has the vectorized solution running two orders of magnitude faster than the loop solution.

Note: I've used a second line in my vectorized solution to mimic your cell array output structure. Up to you whether you want to include it or two combine it into one line etc.

By the way, +1 for posting code in the question. However, two small suggestions for the future: 1) When posting to SO, use simple variable names - especially for loop subscripts - such as I have in my answer. 2) It is nice when we can copy and paste example code straight into a script and run it without having to do any changes or additions (again such as in my answer). This allows us to converge on a solution more rapidly.

Colin T Bowers
  • 18,106
  • 8
  • 61
  • 89
  • Wow thanks for the quick response! The reason I've created a cell array with a vector in each cell is that the 'N' variable is adjustable so I do not know how many vectors are required.. if that makes any sense? – user1878019 Dec 10 '12 at 02:04
  • @user1878019 No probs. If you think my answer is satisfactory, then feel free to mark it answered with the tick mark. Otherwise, let me know if there are any issues, and I'll try and improve the answer. **EDIT:** Yes, that makes sense, I'll update my answer – Colin T Bowers Dec 10 '12 at 02:05
  • @user1878019 Hmmmm... Do you mean that the length of `X` and `Y` is, say `T`, and that sometimes `T` will equal `N`, but sometimes `T` may be greater than `N`? Also, do you know the value of `N` *before* you start the loop? – Colin T Bowers Dec 10 '12 at 02:09
  • Yes X and Y and N are all equal to T but 'T' will change. With a numeric matrix I am guessing that I am able to create a T by T matrix? If that is true then I think the solution posted is perfect but I'm not familiar with the bsxfun and minus functions? Yes the value of N is known before the start of the loop – user1878019 Dec 10 '12 at 02:13
  • Sorry I have googled and am now familiar :) Thank you so much for the help!! – user1878019 Dec 10 '12 at 02:16
  • 2
    @user1878019 `bsxfun` is an incredibly useful function. But it does take a while to get the hang of it, so don't be discouraged at first. In fact, I found it so confusing to start with that I posted [a question dedicated entirely to the use of this function](http://stackoverflow.com/questions/12951453/in-matlab-when-is-it-optimal-to-use-bsxfun). Also, if `N` is known before the start of the loop then my solution is fine. If `N` is ever less than `T`, you can just limit the indices of `X` that are examined in the `bsxfun` line. – Colin T Bowers Dec 10 '12 at 02:18
  • The only other question I have is that the X and X' are actually the same vectors. Will the solution still be the same while implementing the same vector into the bsxfun? – user1878019 Dec 10 '12 at 02:26
  • @user1878019 I'm not sure I understand. `X` and `X'` are slightly different. One is a row vector, the other a column. `bsxfun` exploits this difference using "singleton expansion", ie expanding along whichever dimension (row or column) is equal to 1, hence it subtracts each element from every other element and returns a matrix. You could reverse the order, ie `X'` and `X` and get the same result because you square the output. You could use `X` and `Y'`, but this would give a different answer since you'd be finding the distance between each point of `X` and each point of `Y`... – Colin T Bowers Dec 10 '12 at 02:32