Subtract matrices of different sizes

2.4k Views Asked by At

I have $2$ matrices of different sizes: $8 \times 3$ matrix $A$ and $2 \times 3$ matrix $B$. I need to subtract from each row of $B$, a particular row of $A$ and sum these values. This I need to do for all the rows for $A$ and store the result in another matrix $C$. Is there a way to do this avoiding both for loops?

I can avoid one using bsxfun but seems like I need to use one for loop for iterating over the elements of $A$.

3

There are 3 best solutions below

0
On

If I understand correctly, you want to (1) subtract every row of A from every row of B, and then (2) sum all values within each resulting row.

  1. For step (1) you can use a single bsxfun, but you need to permute dimensions:

    subtractedRows = bsxfun(@minus, B, permute(A,[3 2 1]));
    

    For any m, n, subtractedRows(m,:,n) gives B(m,:)-A(n,:).

  2. For step (2) you only need to sum along second dimension:

    result = squeeze(sum(subtractedRows,2));
    
0
On

By linearity, the sum of the differences is the differences of the sums and you should reduce your matrices to two vectors of $8$ and $2$ sums respectively. Then form the "outer difference" matrix $C_{ij}={S_A}_i-{S_B}_j$.

The "naive" approach takes $8\times2\times(3+2)=80$ additions/subtractions, and the "optimized" one $8\times2+2\times2$, then $8\times2$, for a total of $36$, plus extra storage.

In no case can you dispense with a double loop (at least implicit), as the output is a matrix.

0
On

It sounds like you can sum across the columns of A and B before subtracting and simplify the computation.

If broadcasting is available (newest versions of Matlab and Octave):

C = sum(B, 2) - sum(A, 2)'

If not:

C = repmat(sum(B, 2), [1 rows(A)]) - repmat(sum(A, 2)', [rows(B) 1])