1
A = [1 2 3; 7 6 5]
B = [3 7];
A-B = [1-3 2-3 3-3; 7-7 6-7 5-7];
ans =[-2 -1 0; 0 -1 -2]

This is the operation I want to have done. How could I do it by matrix functions other than the iterative solutions?

erogol
  • 13,156
  • 33
  • 101
  • 155
  • 1
    someone will post the solution very quickly, but check out `repmat` (http://www.mathworks.com/help/matlab/ref/repmat.html) in the meantime. A very useful function. – Dan Becker Nov 15 '12 at 17:13

3 Answers3

3

You do this most conveniently with bsxfun, which automatically expands the arrays to match in size (so that you don't need to use repmat). Note that I need to transpose B so that it's a 2-by-1 array.

A = [1 2 3; 7 6 5]
B = [3 7];

result = bsxfun(@minus,A,B')

result =

-2    -1     0
 0    -1    -2
Jonas
  • 74,690
  • 10
  • 137
  • 177
2

I think that Jonas answer is the best. But just for the record, here is the solution using an explicit repmat:

A = [1 2 3; 7 6 5];
B = [3 7];

sz = size(A);
C = A - repmat(B', [1 sz(2:end)]);

Not only is Jonas' answer simpler, it is actually faster by a factor of 2 for large matrices on my machine.

It's also interesting to note that in the case where A is an n-d array, both these solutions do something quite reasonable. The matrix C will have the following property:

C(k,:,...,:) == A(k,:,...,:) - B(k)

In fact, Jonas' answer will run, and very likely do what you want, in the case where B is m-d, as long as the initial dimensions of A and B' have the same size. You can change the repmat solution to mimic this ... at which point you are starting to reimplement bsxfun!

Dan Becker
  • 1,196
  • 10
  • 18
  • 1
    Perhaps you've already seen it, but @Jonas gave a great answer to a [question of mine](http://stackoverflow.com/questions/12951453/in-matlab-when-is-it-optimal-to-use-bsxfun) precisely on the topic of `bsxfun` versus `repmat` type solutions. – Colin T Bowers Nov 16 '12 at 01:25
1

Normally you can't. Iterative solutions will be necessary, because the problem is poorly defined. Matrix addition/subtraction is only defined for matrices of the same dimensions.

ie:

A =         | 1 2 3 |
            | 7 6 5 |

B =         | 3 7 |

It makes no sense to subtract a 1x2 matrix from a 2x3 matrix.

However, if you multiplied B by some intermediate matrix to make the result a 2x3 matrix, that would work, ie:

B' * Y =    | 3 3 3 |
            | 7 7 7 |

eg:

B' =        diag(B)
   =        | 3 0 |
            | 0 7 |


B' * Y =    | 3 3 3 |
            | 7 7 7 |

Y =         | 1 1 1 |
            | 1 1 1 |

Therefore, A-B'*Y gives a valid, non-iterative solution.

A-(B'*Y) =      | 1 2 3 |  -  | 3 3 3 |
                | 7 6 5 |     | 7 7 7 |

         = A - (diag(B) * Y )

The only "cheat" here is the use of the diag() function, which converts a vector to a strictly-diagonal-matrix. There is a way to manually decompose a set of matrix/vector multiplication operations to manually re-create the diag() function, but that would be more work than my solution above itself.

Good luck!

Cloud
  • 18,753
  • 15
  • 79
  • 153
  • 1
    Dogbert, he explicitly said that he wanted to "subtract each item of a matrix from the corresponding row of another matrix". This seems well-defined to me if you are talking about "subtracting" a 1-d matrix from a 2-D matrix, which appears to be the case that he had in mind. – Dan Becker Nov 15 '12 at 17:39
  • In my opinion, the solution I went for was the most "mathematical" in nature as opposed to "programmatic" (ie: something that could be expressed more easily as a set of formulas rather than a set of procedures and if/else statements). I think this was a fair approximation, because the parent of this question didn't specify what would be the case if B were a 2x2 matrix instead of a 1x2. Also, since he/she mentioned the use of matrix functions, I'm assuming the intent was the use of matrix algebra, and not algorithms :) – Cloud Nov 15 '12 at 17:42