在求解 ODE 时,不是在 matlab 中创建两个 m.files,而是如何使用匿名函数传递参数?
Instead of creating two m.files in matlab when solving ODEs, how could I use anonymous functions to pass parameters?
我希望这两个文件合并为一个 m.file,而不是使用函数来定义带有传递参数的 "monod",我想使用传递参数的匿名函数。所以要结合这两个文件来实现。
%(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)');
您可以简单地在文件中定义一个嵌套函数。完全可以接受的语法。但是,您需要使文件 #2 成为实际函数,因为您无法使用脚本文件定义嵌套函数。为此,只需将其设为不接受任何输入且 returns 不接受任何内容的函数。 :
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
将上述代码复制并粘贴到名为 run_ode.m
的文件中,然后在 MATLAB 命令提示符中键入 run_ode
并按 ENTER。
>> run_ode
您应该会得到想要的结果。
或者,如果您想使用问题标题中引用的匿名函数,您可以改为这样做:
%// 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
现在是一个匿名函数,它接受 6 个输入,并输出一个二元素列向量以用于 ode45
。请注意 ode45
现在已更改,因此 @
已被删除。 monod
现在已经是匿名函数的句柄,因此不需要使用 @
。
我希望这两个文件合并为一个 m.file,而不是使用函数来定义带有传递参数的 "monod",我想使用传递参数的匿名函数。所以要结合这两个文件来实现。
%(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)');
您可以简单地在文件中定义一个嵌套函数。完全可以接受的语法。但是,您需要使文件 #2 成为实际函数,因为您无法使用脚本文件定义嵌套函数。为此,只需将其设为不接受任何输入且 returns 不接受任何内容的函数。 :
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
将上述代码复制并粘贴到名为 run_ode.m
的文件中,然后在 MATLAB 命令提示符中键入 run_ode
并按 ENTER。
>> run_ode
您应该会得到想要的结果。
或者,如果您想使用问题标题中引用的匿名函数,您可以改为这样做:
%// 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
现在是一个匿名函数,它接受 6 个输入,并输出一个二元素列向量以用于 ode45
。请注意 ode45
现在已更改,因此 @
已被删除。 monod
现在已经是匿名函数的句柄,因此不需要使用 @
。