Slice, rearrange and extract output arguments of matlab function

Alec Jacobson

August 06, 2015

weblog/

It is a bit annoying how matlab handles anonymous functions an output arguments. Suppose there's a function called solver that expects to be pass a function handle fval and grad that compute the value and the gradient of some function at point X respectively. Then you'd call `solver like this:

Z = solver(@fval,@grad);

Well, suppose I already have a function grad_fval that computes the gradient and function value at some point X, as in:

[G,f] = grad_fval(X);

It's easy to create an anonymous function to compute the gradient:

grad = @(X) grad_fval(X);

But since anonymous functions can only have one line and the output must match it's impossible to extract the second output argument from grad_fval. I guess the official way to do this is to create a file on my hard drive in the current path, say called fval.m and give it the contents:

function f = fval(X)
  [~,f] = grad_fval(X);
end

This is pretty silly.

Instead, I've created a one-off utility function slice_argout.m which is similar to a lot of get_the_nth_output functions found online. Only here I use the matlab-style slicing to enable full manipulation of the output arguments. In the case above I'd use:

fval = @(X) slice_argout(@grad_fval,[2],X);

If I wanted to reverse the output arguments I could use:

fval_grad = @(X) slice_argout(@grad_fval,[2 1],X);

Here're the contents of slice_argout.m:

function varargout = slice_argout(func,order,varargin)
  % SLICE_ARGOUT Slice (permute, reorder, extract blocks from, etc.) output
  % arguments of a given function.
  % 
  % [O1,O2,O3,...] = slice_argout(func,order,I1,I2,I3, ...)
  % 
  % Calling this is effectively the same as calling:
  % 
  %     [T1,T2,T3,...] = func(I1,I2,I3,...)
  %
  % 
  if islogical(order)
    n = numel(order);
  else
    n = max(order(:));
  end
  varargout = cell(n,1);
  [varargout{:}] = func(varargin{:});
  varargout = varargout(order);
end