Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merging function handles in MATLAB

Tags:

matlab

I'm currently coding a simulation in MATLAB and need some help in regards to an issue that I've been having.

I'm working on a problem where I have n separate anonymous function handles fi stored in cell array, each of which accepts a 1×1 numeric array xi and returns a 1×1 numeric array yi.

I'm trying to combine each of these anonymous function handles into a single anonymous function handle that accepts a single n×1 numeric array X and returns a single n×1 numeric array Y, where the i-th elements of X and Y are xi and yi = fi (xi), respectively.

As an example, let n = 2 and f_1, f_2 be two function handles that input and output 1×1 arrays and are stored in a cell array named functions:

f_1 = @(x_1) x_1^2 
f_2 = @(x_2) x_2^3
functions = {f_1, f_2}

In this example, I basically need to be able to use f_1 and f_2 to construct a function handle F that inputs and outputs a 2×1 numeric array, like so:

F = @(x) [f_1(x(1,1)); f_2(x(2,1))]

The question is how to generalize this for an arbitrary number n of such functions.

like image 412
Berk U. Avatar asked Jan 25 '11 08:01

Berk U.


2 Answers

It is difficult to define such a function using the inline @()-anonymous syntax (because of the requirement for the function’s body to be an expression).

However, it is possible to define a regular function that runs over the items of a given vector and applies the functions from a given cell array to those items:

function y = apply_funcs(f, x)
    assert(length(f) == length(x));
    y = x;
    for i = 1 : length(f)
        y(i) = feval(f{i}, x(i));
    end
end

If it is necessary to pass this function as an argument to another one, just reference it by taking its @-handle:

F = @apply_funcs
like image 76
ib. Avatar answered Sep 28 '22 09:09

ib.


This can be solved using a solution I provided to a similar previous question, although there will be some differences regarding how you format the input arguments. You can achieve what you want using the functions CELLFUN and FEVAL to evaluate your anonymous functions in one line, and the function NUM2CELL to convert your input vector to a cell array to be used by CELLFUN:

f_1 = @(x_1) x_1^2;     %# First anonymous function
f_2 = @(x_2) x_2^3;     %# Second anonymous function
fcnArray = {f_1; f_2};  %# Cell array of function handles
F = @(x) cellfun(@feval,fcnArray(:),num2cell(x(:)));

Note that I used the name fcnArray for the cell array of function handles, since the name functions is already used for the built-in function FUNCTIONS. The colon operator (:) is used to turn fcnArray and the input argument x into column vectors if they aren't already. This ensures that the output is a column vector.

And here are a few test cases:

>> F([2;2])

ans =

     4
     8

>> F([1;3])

ans =

     1
    27
like image 28
gnovice Avatar answered Sep 28 '22 08:09

gnovice