具有时间相关输入的ODE,如何在不使用插值的情况下加速?

时间:2016-04-02 23:49:25

标签: performance matlab ode numerical-integration

我正在尝试解决一个ODE系统,我的输入激励是时间的函数。

我一直在集成函数中使用interp1,但这似乎不是一种非常有效的方法。我知道它不是,因为一旦我将输入激励更改为sin函数,这不需要函数内部interp1调用,我得到了更快的结果。但是,每个步骤进行插值需要大约10-20倍的时间才能收敛。那么,有没有更好的方法来解决任意时间相关激励的ODE,而不需要插值或其他一些技巧来加速?

我只是在这里复制simple example from The MathWorks的修改版本:

输入激励是gradually increasing sin函数,但过了一段时间之后它变为constant amplitude sin函数。

Dt   = 0.01;   % sampling time step
Amp0 = 2;      % Final Amplitude of signal
Dur_G = 10;    % Duration of gradually increasing part of signal 
Dur_tot = 25;  % Duration of total signal
t_G = 0 : Dt : Dur_G; % time of gradual part 
A = linspace(0, Amp0, length(t_G));
carrier_1 = sin(5*t_G); % Unit Normal Signal
carrier_A0 = Amp0*sin(5*t_G);
out_G = A.*carrier_1;   % Gradually Increasing Signal
% Total Signal with Gradual Constant Amplitude Parts
t_C = Dur_G+Dt:Dt:Dur_tot; % time of constant part
out_C = Amp0*sin(5*t_C);   % Signal of constant part
ft = [t_G t_C];    % total time 
f = [out_G out_C]; % total signal
figure; plot(ft, f, '-b'); % input excitation


function dydt = myode(t,y,ft,f)
f = interp1(ft,f,t); % Interpolate the data set (ft,f) at time t
g = 2;               % a constant
dydt = -f.*y + g;    % Evaluate ODE at time t

tspan = [1 5]; ic = 1;
opts = odeset('RelTol',1e-2,'AbsTol',1e-4);
[t,y] = ode45(@(t,y) myode(t,y,ft,f), tspan, ic, opts);

figure;
plot(t,y);

请注意,我仅解释了上述问题的第一部分,即解决逐渐增加sin函数的系统问题。 在第二部分中,我需要为任意输入激励(例如,地面加速度输入)求解它。

1 个答案:

答案 0 :(得分:0)

对于此示例,您可以使用griddedInterpolant类来获得一些加速:

ft = linspace(0,5,25);
f = ft.^2 - ft - 3;
Fp = griddedInterpolant(ft,f);
gt = linspace(1,6,25);
g = 3*sin(gt-0.25);
Gp = griddedInterpolant(gt,g);

tspan = [1 5];
ic = 1;
opts = odeset('RelTol',1e-2,'AbsTol',1e-4);
[t,y] = ode45(@(t,y)myode(t,y,Fp,Gp),tspan,ic,opts);

figure;
plot(t,y);

ODE功能是:

function dydt = myode(t,y,Fp,Gp)
f = Fp(t);        % Interpolate the data set (ft,f) at time t
g = Gp(t);        % Interpolate the data set (gt,g) at time t
dydt = -f.*y + g; % Evaluate ODE at time t

在我的使用R2015b的系统上,对ode45的调用大约快3倍(0.011秒对0.035秒)。切换到ode23可以获得更快的速度。您可以详细了解griddedInterpolant课程here

如果您的实际系统在特定时间点之间离散地切换输入,那么您应该通过分别集成每个案例来分段解决问题。请参阅this questionthis question。如果系统根据状态变量的值进行切换,则应使用event location(请参阅this question)。但是,如果"解决随机时间依赖激励的ODE"意味着您将随机噪声添加到系统中,然后您有SDE而不是ODE,这是一个完全不同的野兽。