Search code examples
matlabfunctionbsxfun

Applying bsxfun to function with multiple output arguments


Let us assume we have a function myfunction with two output arguments

function [ arg1, arg2 ] = myfunction( a, b )
arg1 = a*b;
arg2 = a+b;
end

I want to apply myfunction to vector A and B:

fun = @myfunction;
A = 1:10;
B = 1:17;
[C, D] = bsxfun(fun,A,B)

This gives an error. How can I use bsxfun with functions having multiple output arguments?


Solution

  • bsxfun generates the output from all combinations of orthogonal matrices / vectors. Therefore to make your example work for even one output you have to transpose one of the inputs:

    output1 = bsxfun(@myfunction,A,B.');
    

    But as rayryeng commented, the problem with bsxfun is that it can return only one output. As Cris Luengo suggested in a comment you can instead use arrayfun. The difference is that for arrayfun you have to explicit generate all input combinations by expanding the input 1xN and 1xM vectors to NxM matrices:

    For Matlab 2016b and later:

    [output1, output2] = arrayfun(@myfunction,A.*ones(numel(B),1),B.'.*ones(1,numel(A)));
    

    Matlab pre-2016b:

    [output1, output2] = arrayfun(@myfunction,bsxfun(@times,A,ones(numel(B),1)),bsxfun(@times,B.',ones(1,numel(A))))
    

    Instead of using bsxfun to expand the matrices you could also use repmat- but that's generally a bit slower.

    Btw., If you have a function with many outputs and can't be bothered with writing [output1, output2, output3, ...] = ... you can just save them in a cell:

    outputs = cell(nargout(@myfunction),1);
    [outputs{:}] = arrayfun(@myfunction,....);