1 view (last 30 days)

Given a matrix A in matlab with:

A = [3,1;4,5;7,8]

and another matrix B which could be referred to as some reference points (each row is reference point that is to be compared to each row of A),

B = [1,1;1,2]

I need to compute a matrix C, such that

C = [4,5;25,18;85,72]

Where each row of C is the difference(squared L2 norm) between each row of A and the rows of B. One possible way to do this in MATLAB is to first create a zero matrix C, C = zeros(5,2), and then use double for-loops to fill in the appropriate value. Is there any other efficient/simpler way in MATLAB?

C = zeros(5,2)

for i = 1:rows

for j = 1:rows2

C(i,j) = (norm(A(i,:)-B(j,:)))^2

end

end

David Goodmanson
on 6 Feb 2020

Edited: David Goodmanson
on 12 Feb 2020

Hello Jesujoba,

it looks like A and B must have the same number of columns but can have a different number of rows. The for-loop method and the repmat method (below) agree, although for the integer data I used, repmat is exact but for-loop has some tiny numerical blips. That's because in for-loop, norm takes a square root and you square that out again.

For loops aren't all bad. Repmat may be faster and more efficient when A and B are large, but with for-loop the intent is clearer from just looking at the code. Repmat would require annotation to even know what its task is.

If there are 10 columns and A and B each have 100 rows, then on my PC the calculation by for-loop takes about 140 millisec. Not bad. For 800 rows, for-loop takes less than a sec. Repmat in that case comes in at about .05 sec, and while it can be a point of pride to make things faster, speed and vectorization aren't everything.

To me one of the biggest values of the repmat method is not speed, but as a particular example of messing around with matrices in Matlab. For a small matrix like in this problem, taking out the semicolons on each line illustrates the process.

% data

% sizes of rows and columns

ca = 2;

cb = ca; % required

ra = 3;

rb = 2;

A = randi(10,ra,ca);

B = randi(10,rb,cb);

% method 1

clear C

for i = 1:ra

for j = 1:rb

C(i,j) = (norm(A(i,:)-B(j,:)))^2;

end

end

% method 2

Arep = repmat(A,rb,1);

% make multiple copies of each row of B, stacked vertially

Brep = repmat(B',ra,1);

Brep = reshape(Brep,ca,[])'; % using [] auto calculates the number of columns

Cvals = (Arep-Brep).^2;

C2 = sum(Cvals,2);

C2 = reshape(C2,ra,rb);

C

C2

Sign in to comment.

Steven Lord
on 6 Feb 2020

You can eliminate one of your loops using the vecnorm function.

>> vecnorm(A-B(1, :), 2, 2).^2

ans =

4

25

85

Sign in to comment.

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 1 Comment

## Direct link to this comment

https://uk.mathworks.com/matlabcentral/answers/503479-compute-the-difference-matix-between-a-marix-and-another-matrix-in-matlab#comment_794096

⋮## Direct link to this comment

https://uk.mathworks.com/matlabcentral/answers/503479-compute-the-difference-matix-between-a-marix-and-another-matrix-in-matlab#comment_794096

Sign in to comment.