Matlab - 有时 ode45 需要很长时间才能 return
Matlab - sometimes ode45 takes long time to return
这是代码
global a b c
a=35
b=3
c=28
for R = a-3 : a+3
for N = b-2 : b+2
for L = c-2 : c+2
a=R;
b=N;
c=L;
ode_interupt_demo
plot3(x(:,3), x(:,2), x(:,1));
S= [R N L]
pause(1)
close
end
end
end
function dxdt=fun1(t,x)
global a b c
dxdt(1)=a*(x(2)-x(1));
dxdt(2)=(c-a)*x(1)-x(1)*x(3)+c*x(2);
dxdt(3)=x(1)*x(2)-b*x(3);
dxdt=dxdt';
end
function status = interuptFun(t,y,flag,interupt_time) %#ok<INUSL>
persistent INIT_TIME;
status = 0;
switch(flag)
case 'init'
INIT_TIME = tic;
case 'done'
clear INIT_TIME;
otherwise
elapsed_time = toc(INIT_TIME);
if elapsed_time > interupt_time
clear INIT_TIME;
str = sprintf('%.6f',elapsed_time);
error('interuptFun:Interupt',...
['Interupted integration. Elapsed time is ' str ' seconds.']);
end
end
function ode_interupt_demo
tspan = [0 10]; y0 = [0.5 1 1];
interupt_time = 10;
outputFun= @(t,y,flag)interuptFun(t,y,flag,interupt_time);
opts = odeset('AbsTol',1e-8,'RelTol',1e-5,'OutputFcn',outputFun);
try
[t,x] = ode45(@fun1,tspan,y0,opts);
catch ME
if strcmp(ME.identifier,'interuptFun:Interupt')
disp(ME.message);
% Do other things
else
rethrow(ME); % It's possible the error was due to something else
end
end
在 Matlab 中我正在求解一个微分方程,但有时需要 ode45
很长时间才能 return。我使用了 this post 中建议的代码来解决我的类似问题,但它不会 return 来自 ode45
的值。相反,我得到
??? Undefined variable x.
Error in ==> goo at 13
plot3(x(:,3), x(:,2), x(:,1));
错误如其所言...未定义的变量x
。您没有在代码中的任何地方定义它,但您在第 13 行立即开始使用它。但是,在第 13 行之前有一个函数调用,看起来 ODE 求解是在那里执行的......但是你不从函数调用返回 x
。请记住,函数中定义的任何变量都在局部范围内。这意味着在退出时,那些先前声明的变量将消失...除非您将变量设置为 global
或 persistent
。
因为您想在函数调用后使用 x
,修复代码最简单的方法是修改函数定义,使其 returns x
,然后赋值x
在您使用它之前作为函数调用的输出。
因此,修改您的 ode_interupt_demo
函数声明,使其执行以下操作:
function x = ode_interupt_demo
接下来,让第 12 行执行此操作:
x = ode_interupt_demo;
代码现在应该可以工作了。
这是代码
global a b c
a=35
b=3
c=28
for R = a-3 : a+3
for N = b-2 : b+2
for L = c-2 : c+2
a=R;
b=N;
c=L;
ode_interupt_demo
plot3(x(:,3), x(:,2), x(:,1));
S= [R N L]
pause(1)
close
end
end
end
function dxdt=fun1(t,x)
global a b c
dxdt(1)=a*(x(2)-x(1));
dxdt(2)=(c-a)*x(1)-x(1)*x(3)+c*x(2);
dxdt(3)=x(1)*x(2)-b*x(3);
dxdt=dxdt';
end
function status = interuptFun(t,y,flag,interupt_time) %#ok<INUSL>
persistent INIT_TIME;
status = 0;
switch(flag)
case 'init'
INIT_TIME = tic;
case 'done'
clear INIT_TIME;
otherwise
elapsed_time = toc(INIT_TIME);
if elapsed_time > interupt_time
clear INIT_TIME;
str = sprintf('%.6f',elapsed_time);
error('interuptFun:Interupt',...
['Interupted integration. Elapsed time is ' str ' seconds.']);
end
end
function ode_interupt_demo
tspan = [0 10]; y0 = [0.5 1 1];
interupt_time = 10;
outputFun= @(t,y,flag)interuptFun(t,y,flag,interupt_time);
opts = odeset('AbsTol',1e-8,'RelTol',1e-5,'OutputFcn',outputFun);
try
[t,x] = ode45(@fun1,tspan,y0,opts);
catch ME
if strcmp(ME.identifier,'interuptFun:Interupt')
disp(ME.message);
% Do other things
else
rethrow(ME); % It's possible the error was due to something else
end
end
在 Matlab 中我正在求解一个微分方程,但有时需要 ode45
很长时间才能 return。我使用了 this post 中建议的代码来解决我的类似问题,但它不会 return 来自 ode45
的值。相反,我得到
??? Undefined variable x.
Error in ==> goo at 13
plot3(x(:,3), x(:,2), x(:,1));
错误如其所言...未定义的变量x
。您没有在代码中的任何地方定义它,但您在第 13 行立即开始使用它。但是,在第 13 行之前有一个函数调用,看起来 ODE 求解是在那里执行的......但是你不从函数调用返回 x
。请记住,函数中定义的任何变量都在局部范围内。这意味着在退出时,那些先前声明的变量将消失...除非您将变量设置为 global
或 persistent
。
因为您想在函数调用后使用 x
,修复代码最简单的方法是修改函数定义,使其 returns x
,然后赋值x
在您使用它之前作为函数调用的输出。
因此,修改您的 ode_interupt_demo
函数声明,使其执行以下操作:
function x = ode_interupt_demo
接下来,让第 12 行执行此操作:
x = ode_interupt_demo;
代码现在应该可以工作了。