Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write an anonymous function with a variable number of output arguments?

Using deal we can write anonymous functions that have multiple output arguments, like for example

minmax = @(x)deal(min(x),max(x));
[u,v] = minmax([1,2,3,4]); % outputs u = 1, v = 4

But if you want to provide a function with its gradient to the optimization function fminunc this does not work. The function fminunc calls the input function sometimes with one and sometimes with two output arguments. (EDIT: This is not true, you just have to specify whether you actually want to use the gradient or not, using e.g. optimset('SpecifyObjectiveGradient',true). Then within one call it always asks for the same number of arguments.)

We have to provide something like

function [f,g] = myFun(x)
 f = x^2; % function
 g = 2*x; % gradient

which can be called with one or two output arguments.

So is there a way to do the same inline without using the function keyword?

like image 818
flawr Avatar asked Jan 25 '18 12:01

flawr


1 Answers

Yes there is, it involves a technique used in this question about recursive anonymous functions. First we define a helper function

helper = @(c,n)deal(c{1:n});

which accepts a cell array c of the possible outputs as well as an integer n that says how many outputs we need. To write our actual function we just need to define the cell array and pass nargout (the number of expected output arguments) to helper:

myFun = @(x)helper({x^2,2*x,2},nargout);

This now works perfectly when calling fminunc:

x = fminunc(myFun,1);
like image 126
flawr Avatar answered Sep 22 '22 02:09

flawr