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
end
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;
end
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
) in either of the two arraysthen 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.