MATLAB Language Vectorization Use of bsxfun


Quite often, the reason why code has been written in a for loop is to compute values from 'nearby' ones. The function bsxfun can often be used to do this in a more succinct fashion.

For example, assume that you wish to perform a columnwise operation on the matrix B, subtracting the mean of each column from it:

B = round(randn(5)*10);                  % Generate random data 
A = zeros(size(B));                      % Preallocate array
for col = 1:size(B,2);                    % Loop over columns
    A(:,col) = B(:,col) - mean(B(:,col));   % Subtract means 

This method is inefficient if B is large, often due to MATLAB having to move the contents of variables around in memory. By using bsxfun, one can do the same job neatly and easily in just a single line:

A = bsxfun(@minus, B, mean(B));

Here, @minus is a function handle to the minus operator (-) and will be applied between elements of the two matrices B and mean(B). Other function handles, even user-defined ones, are possible as well.

Next, suppose you want to add row vector v to each row in matrix A:

v = [1,  2,  3];

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

The naive approach is use a loop (do not do this):

B = zeros(3);
for row = 1:3
    B(row,:) = A(row,:) + v;

Another option would be to replicate v with repmat (do not do this either):

>> v = repmat(v,3,1)
v =
     1     2     3
     1     2     3
     1     2     3

>> B = A + v; 

Instead use bsxfun for this task:

>> B = bsxfun(@plus, A, v);
B =
     9     3     9
     4     7    10
     5    11     5


bsxfun(@fun, A, B)

where @fun is one of the supported functions and the two arrays A and B respect the two conditions below.

The name bsxfun helps to understand how the function works and it stands for Binary FUNction with Singleton eXpansion. In other words, if:

  1. two arrays share the same dimensions except for one
  2. and the discordant dimension is a singleton (i.e. has a size of 1) in either of the two arrays

then the array with the singleton dimension will be expanded to match the dimension of the other array. After the expansion, a binary function is applied elementwise on the two arrays.

For example, let A be an M-by-N-byK array and B is an M-by-N array. Firstly, their first two dimensions have corresponding sizes. Secondly, A has K layers while B has implicitly only 1, hence it is a singleton. All conditions are met and B will be replicated to match the 3rd dimension of A.

In other languages, this is commonly referred to as broadcasting and happens automatically in Python (numpy) and Octave.

The function, @fun, must be a binary function meaning it must take exactly two inputs.


Internally, bsxfun does not replicate the array and executes an efficient loop.