Is there a way to pass an anonymous function with an unknown number of variables to a matlab function and perform operations on it?

23 views (last 30 days)
Basically what I want to do is take in an anonymous function like:
Afunc = @(a,b,c,...) a+b+c+...; % for any number of variables
and pass it and values for each variable (say in an n-dimensional matrix where n is the number of variables in Afunc) into a matlab function that will evaluate it at all points. So:
Amatrix = AfuncEval(Afunc,vals);
An example using 3 variables:
Afunc = @(a,b,c) a+b+c;
vals = [[1 2 3];[4 5 6];[7 8 9]]; % vals(1,:) are values for variable a, vals(2,:) are b, etc.
Amatrix = AfuncEval(Afunc,vals);
Amatrix(1,1,1) = Afunc(1,4,7);
Amatrix(1,1,2) = Afunc(1,4,8);
And so on. I've looked all over and haven't managed to find a completely general approach to anonymous functions. The closest I've come is using a cell function:
cellfun(Afunc,val{:});
but this only evaluates Afunc at (1,4,7), (2,5,8), and (3,6,9). I could set up val so that it evaluates Afunc at all combinations of the variable values, but that would still require knowing how many variables there are ahead of time. Has anyone tried to do anything like this before?
Thanks very much!

Accepted Answer

Yakboy287
Yakboy287 on 19 Dec 2013
Function for evaluating any anonymous function with any number of value inputs (tested up through 4 dimensions, haven't bothered with higher ones yet.
% function funcEval(func,vals)
% Takes in an anonymous function and an nxm matrix of values and returns an
% n-dimensional matrix filled with the function evaluated at all points
% given in val. That is at all combinations of all the inputs in val.
%
% inputs:
% Afunc - the anonymous function to be normalized
% vals - nxm cell matrix of values corresponding to each variable in Afunc
% as follows:
% Afunc = @(a,b,c) f(a,b,c)
% val = [...
% [1,2,3,4,5,...] % corresponds to a
% [1,2,3,4,5,...] % corresponds to b
% [1,2,3,4,5,...] % corresponds to c
% ...
% ]
%
% output:
% fMatrix - a matrix containing func evaluated at all combinations of
% variable values in val. So for a two variable function with
% three values for each variable:
% fMatrix(1,1) = func(val(1,1),val(2,1));
% fMatrix(1,2) = func(val(1,1),val(2,2));
% fMatrix(1,3) = func(val(1,1),val(2,3));
% fMatrix(2,1) = func(val(1,2),val(2,1));
% fMatrix(2,2) = func(val(1,2),val(2,2));
% fMatrix(2,3) = func(val(1,2),val(2,3));
% fMatrix(3,1) = func(val(1,3),val(2,1));
% fMatrix(3,2) = func(val(1,3),val(2,2));
% fMatrix(3,3) = func(val(1,3),val(2,3));
%
% 3-dimensional example:
% Inputs:
% func = @(a,b,c) a.^b + c;
% vals =
% 2 5 10
% 1 2 3
% .1 .2 .3
%
% Output:
% fMatrix(:,:,1) =
%
% 2.1 4.1 8.1
% 5.1 25.1 125.1
% 10.1 100.1 1000.1
%
%
% fMatrix(:,:,2) =
%
% 2.2 4.2 8.2
% 5.2 25.2 125.2
% 10.2 100.2 1000.2
%
%
% fMatrix(:,:,3) =
%
% 2.3 4.3 8.3
% 5.3 25.3 125.3
% 10.3 100.3 1000.3
%%
function fMatrix = funcEval(func,vals)
nvars = size(vals,1); % number of variables
vals_cell = mat2cell(vals, ones(nvars,1), size(vals,2));
vals_grids = cell(nvars,1);
[vals_grids{:}] = ndgrid(vals_cell{:});
vals_2d = cell(nvars,1);
for i=1:nvars
vals_2d{i} = vals_grids{i}(:);
end; % end for i
% Getting matrix2d - this will be turned into fMatrix which is nvars
% dimensions rather than two dimensions.
fSolutions = nan(1,size(vals_2d{1,:},1));
solution = cell(nvars,1);
for i=1:size(vals_2d{1,:},1)
for j=1:size(vals_2d,1)
solution{j} = vals_2d{j}(i);
end % end for j
fSolutions(i) = func(solution{:}); % 2-d version of fMatrix
end % end for i
%filling fMatrix, an nvars dimensional matrix
sizeM = size(vals_grids{1});
fMatrix = reshape(fSolutions,sizeM);
end % end funcEval_jfr001

More Answers (1)

Walter Roberson
Walter Roberson on 18 Dec 2013
function r = AfuncEval(Afunc, vals)
nvars = size(vals,1);
vals_cell = mat2cell(vals, ones(nvars,1), size(vals,2));
vals_grids = cell(nvars,1);
[vals_grids{:}] = ndgrid(vals_cell{:});
r = Afunc(vals_grids{:});
end
  2 Comments
Yakboy287
Yakboy287 on 19 Dec 2013
Thanks very much! That got me to the answer, though
r = Afunc(vals_grids{:});
only works for a two dimensional vals_grids. I was able to condense higher dimensions to two dimensions, then re-shape the result into an n dimensional matrix. I've posted my full function (including examples in the comments) as an answer to this thread if anyone is interested.

Sign in to comment.

Categories

Find more on Financial Toolbox in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!