2

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?

Umberto D.
  • 215
  • 1
  • 2
  • 6
  • If you replace the `*` by `.*` then your function will be able to take `A` and `B` and produce your desired result. Since the inputs do not have different shapes, `bsxfun` will not do anything special. – Cris Luengo Dec 10 '17 at 02:16
  • 1
    Maybe you want to use `arrayfun` instead? – Cris Luengo Dec 10 '17 at 04:17
  • How could I use `arrayfun` to produce as many `m x n` matrices as the number of output arguments of `myfunction`? – Umberto D. Dec 10 '17 at 08:16
  • 1
    Did you read the help for `arrayfun`? It seems to me that `[C, D] = arrayfun(fun,A,B)` would do what you want. – Cris Luengo Dec 10 '17 at 14:16
  • Also, after the edit of your question, A and B are no longer compatible. `bsxfun` would no longer work either. – Cris Luengo Dec 10 '17 at 14:17

2 Answers2

2

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,....);
Leander Moesinger
  • 2,449
  • 15
  • 28
0

You cannot, the bsxfun is only for binary operations

Nicky Mattsson
  • 3,052
  • 12
  • 28
  • 1
    What do you mean by "binary" operations? This wording is unclear to me. I think you mean that `bsxfun` does not work for multiple outputs. It only provides one output. – rayryeng Dec 10 '17 at 07:40
  • I mean this: https://en.wikipedia.org/wiki/Binary_operation. In what way is that unclear? – Nicky Mattsson Dec 11 '17 at 09:20