manoos
manoos

Reputation: 1735

How to use dynamic function name in MATLAB?

I am trying to optimize the following program by using for loops

t = 0:0.1:100;   
conc = rand(size(t));

syms x

equ_1(x) = 10*x.^2+1;
equ_2(x) = 5*x.^3+10*x.^2;
equ_3(x) = 5*x.^3+10*x.^2;

y_1 = equ_1(conc);
y_2 = equ_2(conc);
y_3 = equ_3(conc);

p_1 = polyfit(t,y_1,1);
p_2 = polyfit(t,y_2,1);
p_3 = polyfit(t,y_3,1);

yfit_1 = p_1(1)*conc+p_1(2);
yfit_2 = p_2(1)*conc+p_2(2);
yfit_3 = p_2(1)*conc+p_2(2);

rms_er_1 = double(sqrt((sum((yfit_1-y_1).^2)./length(yfit_1))));
rms_er_2 = double(sqrt((sum((yfit_2-y_2).^2)./length(yfit_2))));
rms_er_3 = double(sqrt((sum((yfit_3-y_3).^2)./length(yfit_3))));


rms = [rms_er_1 rms_er_2 rms_er_3]

In this program. I have many equations and I can write them manually like equ_1(x),equ_1(x),equ_1(x) etc. After writing equations, will it be possible to write remaining programs by using for loops?

Can anyone help?

Upvotes: 0

Views: 125

Answers (2)

PilouPili
PilouPili

Reputation: 2699

You can try cellfun

Here is an example.

Define in a .m

function y = your_complex_operation(f,x, t)
y_1 = f(x);
p_1 = polyfit(t,y_1,1);
yfit_1 = p_1(1)*x+p_1(2);
y = double(sqrt((sum((yfit_1-y_1).^2)./length(yfit_1))));
end

Then use cellfunc

funs{1}=@(x) 10*x.^2+1;
funs{2}=@(x) 5*x.^3+10*x.^2;
funs{3}=@(x) 5*x.^3+10*x.^2;
%as many as you need

t = 0:0.1:100;
conc = rand(size(t));

funs_res = cellfun(@(c) your_complex_operation(c,conc,t),funs);

Upvotes: 0

gehbiszumeis
gehbiszumeis

Reputation: 3711

Yes, it is possible. You can pack your functions in a cell array and give your values as parameters while looping over this cell array

t = (0:0.1:100)';   
conc = rand(size(t));

% Packing your function handles in a cell array ( I do not have the 
% symbolic math toolbox, so I used function handles here. In your case you
% have to pack your equations equ_n(x) in between the curly brackets{} )
allfuns = {@(x) 10*x.^2+1, ...
    @(x) 5*x.^3+10*x.^2, ...
    @(x) 5*x.^3+10*x.^2};

% Allocate memory
y = zeros(length(t), length(allfuns));
p = zeros(2,length(allfuns));
yfit = zeros(length(t), length(allfuns));
rms = zeros(1, length(allfuns));

% Loop over all functions the cell, applying your functional chain
for i=1:length(allfuns)
    y(:,i) = allfuns{i}(t);
    p(:,i) = polyfit(t,y(:,i),1);
    yfit(:,i) = p(1,i)*conc+p(2,i);
    rms(:,i) = double(sqrt((sum((yfit(:,i)-y(:,i)).^2)./ ...
        length(yfit(:,i)))));
end

This leads to

>> rms

rms =

   1.0e+06 *

    0.0578    2.6999    2.6999

You can expand that to an arbitrary number of equations in allfuns.

Btw: You are fitting 1st order polynomials with polyfit to values calculated with 2nd and 3rd order functions. This leads of course to rough fits with high rms. I do not know how your complete problem looks like, but you could define an array poly_orders containing the polynomial order of each function in allfuns. If you give those values as parameter to the polyfit function in the loop, your fits will work way better.

Upvotes: 2

Related Questions