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 (EDIT: This is not true, you just have to specify whether you actually want to use the gradient or not, using e.g. fminunc
calls the input function sometimes with one and sometimes with two output arguments.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?
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With