Vectorize comparing a column vector in a matrix to all other vectors in the matrix.

Hello,
I am trying to take the difference between a column in a matrix to the rest of the matrix but I am trying to do it without using a loop is this possible? Additionally, would doing it without the loop be more efficient, or would you have to spend a bunch of time in overhead to set it up so that you can do it vectorized?
Example Code:
% Variable Definitions
A.a = rand(10,11);
A.b = rand(10,11);
A.c = rand(10,11);
% Memory Pre-allocation
d = zeros(10,11);
e = zeros(1,11);
% Loop
for i = 1:size(A.a,2)
a = A.a - A.a(:,i);
b = A.b - A.b(:,i);
c = A.c - A.c(:,i);
d = sqrt(a.^2 + b.^2 + c.^2);
e(i) = max(max(d));
end
% The line below shows that knowing the column
% of that the maximum values are in is important.
[~, index] = min(e);
%% Alternatively it could look something like the below
for i = 1:size(A.a,2)
a(:,:,i) = A.a - A.a(:,i);
b(:,:,i) = A.b - A.b(:,i);
c(:,:,i) = A.c - A.c(:,i);
end
d = sqrt(a.^2 + b.^2 +c.^2);
e = max(max(d));
% But I want to do it without having to do the loop? Is this possible.

 Accepted Answer

Why do you want to vectorize this code? I assume, this will cause a slow down, because this creates large temporary array, which are not needed.
If you want to speed it up, other methods are more useful
  1. Accessing a field of a struct costs time. Create a temporary variable instead. This does not duplicate the data, but creates a shared data copy.
  2. SQRT is expensive. You want to find the minimum value of an array. Then search the minimum at first and calculate only its SQRT.
  3. Pre-allocating d is useless and therefore a waste of time: d is not used later, but overwritten.
% Memory Pre-allocation
e = zeros(1,11);
Aa = A.a; % Abbreviations
Ab = A.b;
Ac = A.c;
% Loop
for i = 1:size(Aa,2)
a = Aa - Aa(:,i);
b = Ab - Ab(:,i);
c = Ac - Ac(:,i);
d = (a.^2 + b.^2 + c.^2);
e(i) = sqrt(max(max(d)));
end

More Answers (1)

You can use repmat.m to make a matrix of the same size.
a = A.a - repmat(A.a(:,1),1,size(A.a,2))
b = A.b - repmat(A.b(:,1),1,size(A.b,2))
c = A.c - repmat(A.c(:,1),1,size(A.c,2))

2 Comments

The issue is this only compares the first column to every other column instead of every column to every other column. For instance I want to get the difference of the element from column 1 row 1 to the element from column 2 row 1 and column 3 row 1 etc. for all of the columns then compare column 1 row 2 to the elment from column 2 row 2 etc. After all of that I want to compare column 2 row 1 to column 1 row 1 then column 2 row 1 then column 3 row 1 etc.
So in the code I wrote I did:
A.a-A.a(:,i);
Which gets the difference of the first column against every other column and every loop it gets the difference of the next column.
I edit the question to give an alternative example but it still has the loop which I think is less efficent but am not sure?

Sign in to comment.

Products

Release

R2019b

Asked:

on 23 Jun 2022

Commented:

on 24 Jun 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!