Search code examples
matlablistfunctionanonymous-functionevaluate

How do you evaluate functions from list in MATLAB


I have a problem where I need evaluate a bunch of functions that are stored in a list.

I have a function dg and parameter values for 'a' and 'b' in paramList:

syms a b x;
dg = symfun((a*exp(-a*(x-b)))/((1+exp(-a*(x-b)))^2),[a b x]);
paramList = [0.18, 20; 0.25, 25; 0.35, 15; 0.3, 20; 0.33, 30];

and need to make a list of this functions f(x) with different parameter values for 'a' and 'b'.

I have a function that can do this:

function [ out ] = getFunList( paramList, func )
    syms a b x;
    s = size(paramList);
    s = s(1);
    out = symfun.empty(1,s);
    for i = 1:s
        newFun = subs(func,a,paramList(i,1));
        newFun = subs(newFun,b,paramList(i,2));
        out(1,i) = newFun;
    end
end

Using the above function will result in

>> funList = getFunList(paramList,dg)

funList =

[ (9*exp(18/5 - (9*x)/50))/(50*(exp(18/5 - (9*x)/50) + 1)^2), exp(25/4 - x/4)/(4*(exp(25/4 - x/4) + 1)^2), (7*exp(21/4 - (7*x)/20))/(20*(exp(21/4 - (7*x)/20) + 1)^2), (3*exp(6 - (3*x)/10))/(10*(exp(6 - (3*x)/10) + 1)^2), (33*exp(99/10 - (33*x)/100))/(100*(exp(99/10 - (33*x)/100) + 1)^2)]

but if I try to evaluate from here it doesn't work:

 >> subs(funList(1,1),x,5)

 ans =

 (9*exp(27/10))/(50*(exp(27/10) + 1)^2)

Is there any way get the last expression to evaluate exactly?

>> eval(funList(1))

ans =

(9*exp(18/5 - (9*x)/50))/(50*(exp(18/5 - (9*x)/50) + 1)^2)

doesn't work.

Or is there a good way to store a cell array of anonymous functions? I tried this but I can't figure out how to create the anonymous functions from variables. For example:

>> cellarr = cell(1,3)
>> cellarr{1} = @(x) eval(funList(1))

cellarr = 

      @(x)eval(funList(1))    []    []

>> 

This doesn't produce what I want. I'm not sure how to get the the cell array to store

@(x) (9*exp(18/5 - (9*x)/50))/(50*(exp(18/5 - (9*x)/50) + 1)^2)

but extracted from a variable.

Any help would be great. Thanks.


Solution

  • Do you really need a symfun? It seems function handles are fine in your case.

    f=@(a,b,x)((a*exp(-a*(x-b)))/((1+exp(-a*(x-b)))^2))
    paramList = [0.18, 20; 0.25, 25; 0.35, 15; 0.3, 20; 0.33, 30];
    for rw=1:size(paramList,1)
       fcnList{rw}=@(x)f(paramList(rw,1),paramList(rw,2),x);
    end
    

    This generates the list. In case you simply want to evaluate use:

    fcnList{1}(5)
    

    Or to get the expression:

    fcnList{1}(sym('x'))
    

    It is important to keep functions in a cell array. Arrays of functions are not possible. For symfuns you get a function returning an array instead of an array of functions.