3

Given a matrix and a vector

A = [ 1 2; 2 4 ];
v = [ 2 4 ];

how can I divide each column of the matrix by the respective element of the vector? The following matrix should be

[ 1/2 2/4; 2/2 4/4 ]

Basically I want to apply a column-wise operation, with operands for each column stored in a separate vector.

Jakub Arnold
  • 85,596
  • 89
  • 230
  • 327

2 Answers2

5

You should use a combination of rdivide and bsxfun:

A = [ 1 2; 2 4 ];
v = [ 2 4 ];
B = bsxfun(@rdivide, A, v);

rdivide takes care of the per element division, while bsxfun makes sure that the dimensions add up. You can achieve the same result by something like

B = A ./ repmat(v, size(A,1), 1)

however, using repmat results in an increased memory usage, which is why the bsxfun solution is preferable.

jdoerrie
  • 531
  • 4
  • 6
  • `bsxfun` performs the replication and hence also has an increase in memory usage under the hood as well so you may need to be careful in your last assertion in your answer. However, it is most certainly faster than `repmat` so good choice on that. See some great benchmarks here: http://stackoverflow.com/questions/12951453/in-matlab-when-is-it-optimal-to-use-bsxfun. Also, see here on memory usage with `bsxfun`: http://stackoverflow.com/questions/29800560/bsxfun-on-memory-efficiency-with-relational-operations – rayryeng Jul 13 '15 at 23:16
  • Thanks for the pointers, that is very interesting. I was under the impression that `bsxfun` is simply reusing the existing array, but I don't think I have an actual reference on that. But I agree, `bsxfun` is both faster and more memory efficient than `repmat`, so there isn't any reason to not use it. – jdoerrie Jul 13 '15 at 23:30
  • 1
    Actually looking at the second post, the memory use is increased, but it's very minimal compared to `repmat`, so I think you're right on the money with your last assertion. I take that back! – rayryeng Jul 13 '15 at 23:32
2

Use bsxfun with the right divide (rdivide) operator and take advantage of broadcasting:

>> A = [ 1 2; 2 4 ];
>> v = [ 2 4 ];
>> out = bsxfun(@rdivide, A, v)

out =

    0.5000    0.5000
    1.0000    1.0000

The beauty with bsxfun is that in this case, the values of v will be replicated for as many rows as there are in A, and it will perform an element wise division with this temporary replicated matrix with the values in A.

rayryeng
  • 102,964
  • 22
  • 184
  • 193