L.Brian
L.Brian

Reputation: 13

Instead of creating two m.files in matlab when solving ODEs, how could I use anonymous functions to pass parameters?

i want these two files to combine into one m.file, instead of using function to define the "monod" with passing parameters, i want to use anonymous functions passing the parameters. So to achieve in combining both two files.

%(file 1)
function dcdt = monod(t,c,k,ks,y,b)
dcdt = zeros(2,1);
dcdt(1) = -k*c(2)*c(1)/(ks+c(1));
dcdt(2) = y*k*c(2)*c(1)/(ks+c(1))-b*c(2);
% (file 2) ODE45
k = 3.7;ks=30;y=0.03;b=0.01;
options = odeset('Reltol',1.e-10,'AbsTol',1.e-10);
[t,c] = ode45(@monod, [0,200],[200,1],options,k,ks,y,b);
% plot 
C = c(:,1);
Xa = c(:,2);
figure(1);
grid on;
subplot(2,1,1);
plot(t,C);
title('Substrate aqueous concentration vs time(ODE45)');
xlabel('time');ylabel('Substrate aqueous concentration C')
subplot(2,1,2);
plot(t,Xa);
title('Active-cell concentration vs time');
xlabel('time');ylabel('Active-cell concentration Xa(ODE45)');

Upvotes: 1

Views: 85

Answers (1)

rayryeng
rayryeng

Reputation: 104503

You can simply define a nested function within your file. Perfectly acceptable syntax. However, you will need to make File #2 an actual function as you can't define nested functions with a script file. To do this, just make it a function that accepts no inputs and returns nothing. :

function run_ode %// Change here

    %// Include monod function here - watch the end keyword
    function dcdt = monod(t,c,k,ks,y,b)
        dcdt = zeros(2,1);
        dcdt(1) = -k*c(2)*c(1)/(ks+c(1));
        dcdt(2) = y*k*c(2)*c(1)/(ks+c(1))-b*c(2);
    end %<----

%// Begin File #2
k = 3.7;ks=30;y=0.03;b=0.01;
options = odeset('Reltol',1.e-10,'AbsTol',1.e-10);
[t,c] = ode45(@monod, [0,200],[200,1],options,k,ks,y,b);
% plot 
C = c(:,1);
Xa = c(:,2);
figure(1);
grid on;
subplot(2,1,1);
plot(t,C);
title('Substrate aqueous concentration vs time(ODE45)');
xlabel('time');ylabel('Substrate aqueous concentration C')
subplot(2,1,2);
plot(t,Xa);
title('Active-cell concentration vs time');
xlabel('time');ylabel('Active-cell concentration Xa(ODE45)');

end %// Take note of this end too as we now have nested functions

Copy and paste the above code into a file called run_ode.m, then in the MATLAB Command Prompt, type in run_ode and push ENTER.

>> run_ode

You should get your desired results.


Alternatively, if you want to make use of anonymous functions as referenced in your question title, you can do this instead:

%// Change here
monod = @(t,c,k,ks,y,b) [-k*c(2)*c(1)/(ks+c(1)); y*k*c(2)*c(1)/(ks+c(1))-b*c(2)];

k = 3.7;ks=30;y=0.03;b=0.01;
options = odeset('Reltol',1.e-10,'AbsTol',1.e-10);
[t,c] = ode45(monod, [0,200],[200,1],options,k,ks,y,b); %// Change here too
% plot 
C = c(:,1);
Xa = c(:,2);
figure(1);
grid on;
subplot(2,1,1);
plot(t,C);
title('Substrate aqueous concentration vs time(ODE45)');
xlabel('time');ylabel('Substrate aqueous concentration C')
subplot(2,1,2);
plot(t,Xa);
title('Active-cell concentration vs time');
xlabel('time');ylabel('Active-cell concentration Xa(ODE45)');

monod is now an anonymous function that takes in the 6 inputs, and outputs a two element column vector for use in ode45. Take note that ode45 is now changed so that the @ is removed. monod is now already a handle to an anonymous function and so using @ is not required.

Upvotes: 1

Related Questions