在ode45循环内集成问题

时间:2014-02-01 08:25:48

标签: matlab ode numerical-integration

当我尝试使用这个Matlab代码时,它会进入无限循环。我正在尝试在ode45中执行集成:

clear
clc
options = odeset('RelTol',1e-4,'AbsTol',[1e-4 1e-4 1e-5]);
[T,Y] = ode45(@rigid,[0 12],[0 1 1],options);

plot(T,Y(:,1),'+',T,Y(:,2),'*',T,Y(:,3),'.')


function dy = rigid(t,y)
dy = zeros(3,1);    % a column vector

dy(1) = y(2) ;

dy(2) = -y(1) * y(3);
fun = @(t) exp(-t.^2).*log(t).^2+y(1);
q = integral(fun,0,Inf);
dy(3) = y(2) * y(3) + q;

1 个答案:

答案 0 :(得分:0)

没有“无限循环”。您的功能需要很长时间才能集成。尝试将tspan设置为[0 1e-7]。它似乎是一个高频振荡,但我不知道你的方程是否正确(这是一个数学问题,而不是编程问题)。这些系统难以准确集成(ode15可能是更好的选择),更不用说了。

您也没有理由提到integral的调用产生警告信息的重要事实:

Warning: Minimum step size reached near x = 1.75484e+22. There may be a
singularity, or the tolerances may be too tight for this problem. 
> In funfun/private/integralCalc>checkSpacing at 457
  In funfun/private/integralCalc>iterateScalarValued at 320
  In funfun/private/integralCalc>vadapt at 133
  In funfun/private/integralCalc at 84
  In integral at 88
  In rtest1>rigid at 17
  In ode15s at 580
  In rtest1 at 5 

在每次迭代时打印出警告消息会大大降低集成速度。这个警告有充分的理由。您确实意识到,您使用integral0Inf评估的功能等同于以下内容,对吧?

sqrt(pi)*((eulergamma + log(4))^2/8 + pi^2/16) + Inf*y(1)

其中eulergammapsi(1)double(sym('eulergamma'))。你的被积函数不会收敛。

如果您愿意,可以尝试以两种方式之一避免警告信息。

1。关闭警告(确保之后重新启用)。您可以使用以下代码执行此操作:

...
warning('OFF','MATLAB:integral:MinStepSize');
[T,Y] = ode45(@rigid,[0 12],[0 1 1],options);
warning('ON','MATLAB:integral:MinStepSize');
...

您可以通过lastwarn功能获取waring的ID。

2. 另一种选择可能是更改集成界限并完全避免警告,例如:

...
q = integral(fun,0,1e20);
...

这可能是也可能是不可接受的,但是integral并没有返回正确的解决方案,因为结果不会收敛。