MATLAB: Programatically creating an anonymous function that separates “Variables” and “Parameters”

anonymous functionsfunction restrictionMATLABvarargin

I have a function MYFUN with several inputs.
Say,
myfun = @(a,b,c,d) a*1000 + b*100 + c*10 + d
In actuality, some of these inputs are fixed “Parameters”, and others are the actual “Variables”, so I would like to have a function “Simplify”, such that
SIMPFUN = Simplify(FUN,PAR1,PAR2,..,PARN)
gets a function handle FUN and parameters PAR1, PAR2,… and returns a simplified function SIMPFUN, such that any non-empty PARs (which are my "Parameters") are substituted into the workspace of SIMPFUN and SIMPFUN only needs to get the empty PARS (which are the "Variables").
For example,
myfun = @(a,b,c,d) a*1000 + b*100 + c*10 + d ;
myfun(1,2,3,4)
ans =
1234
simp_myfun = Simplify(myfun,1,[],3,4) ;
simp_myfun(2)
ans =
1234
simp_myfun = Simplify(myfun,1,[],3,[]) ;
simp_myfun(2,4)
ans =
1234
simp_myfun(8,9)
ans =
1839
I have an implementation that works correctly, but is based on nested functions (cumbersome) and
I wonder if there is a more elegant solution based on anonymous functions.
Here is my current implementation:
function SimplifiedFcn = Simplify(Fcn,varargin)
isEmpty = cellfun(@isempty, varargin) ;
fEmp = find(isEmpty) ;
fnEmp = find(~isEmpty) ;
nonEmptyVars = varargin(fnEmp) ;
[~,k] = sort([fEmp fnEmp]) ;
SimplifiedFcn = @getfun ;
function Val = getfun(varargin)
Vars = [varargin, nonEmptyVars] ;
Val = Fcn(Vars{k}) ;
end
end

Best Answer

You won't be able to do this with just anonymous functions, they're too limited in matlab (no multiple statements, no branching).
This is more or less similar to what you have, only simpler and not using nested functions. In addition it allows for functions that return more than one output:
function f = Simplify(fcn, varargin)
inputloc = find(cellfun(@isempty, varargin));
inputpack = varargin;
f = @(varargin) insertinputs(fcn, inputpack, inputloc, varargin);
end
function varargout = insertinputs(fcn, inputpack, inputloc, newinputs)
inputdiff = {'Not enough', '', 'Too many'};
assert(numel(inputloc) == numel(newinputs), '%s input arguments to simplified function', inputdiff{sign(numel(newinputs)-numel(inputloc))+2});
inputpack(inputloc) = newinputs;
[varargout{1:nargout}] = fcn(inputpack{:});
end