通过在Matlab中计算ODE函数中的ODE值来检测稳态

时间:2016-04-17 14:16:39

标签: matlab if-statement conditional-statements ode

我有一个ODE方程系统,我想解决,但有一个棘手的部分,当系统达到稳态时,我想改变一个(或多个)参数的值。例如,请考虑以下事项:

function dydt = diff(t,x,params)
   F = params(1);
   G = params(2);
   dydt = zeros(2,1);
   dydt(1) = F*x(1) - G*x(1)*x(2);
   dydt(2) = (F-G)*x(2);
end

我希望我的代码工作,以便当系统达到稳定状态时,F的值更改为10,并且G的值更改为2,例如。我想通过使用,例如,

来检测dydt(1)和dydt(2)的值
if norm(dydt)<1
   F = 10;
   G = 2;
end

我如何在Matlab中为ODE表达式做到这一点?如果我把这条if条件放在ODE表达式之前,那么dydt的值总是为零。但是,如果我在ODE表达式之后放置此If条件,则If条件将无法用于更正ODE表达式。

谢谢!

1 个答案:

答案 0 :(得分:0)

假设ODE的参数是固定的,并且不依赖于系统的状态。你要做的是模拟分段连续ODE。这类问题通常用event location解决(假设存在解决方案)。您需要在关键点停止模拟,更改参数,然后使用与上一个条件相同的初始条件重新启动新模拟。

这是ODE功能的一个小例子。我不知道您的初始条件,初始参数值或其他设置,所以这只是为了演示这个方案:

function eventsdemo
params = [-1.5 1];
tspan = [0 10];
x0 = [1;1];
opts = odeset('Events',@events);
[t1,x1] = ode45(@(t,x)f(t,x,params),tspan,x0,opts); % Simulate with events

% Change parameters, set initial conditions based on end of previous run
params = [1.5 1];
x0 = x1(end,:);
tspan = [t1(end) 10];
[t2,x2] = ode45(@(t,x)f(t,x,params),tspan,x0); % Simulate again

% Concatenate results, removing duplicate points
t = [t1;t2(2:end)];
x = [x1;x2(2:end,:)];

figure;
plot(t,x);
hold on;
plot(t2(1),x2(1,:),'k*'); % Plot event location


function dxdt = f(t,x,params) %#ok<INUSL>
F = params(1);
G = params(2);
dxdt = [F*x(1) - G*x(1)*x(2);
        (F-G)*x(2)];


function [value,isterminal,direction] = events(t,x) %#ok<INUSL>
value = norm(x)-1e-3; % Don't try to detect exact zero for asymptotics
isterminal = true;
direction = -1;

在这种情况下,解决方案渐近地接近(0,0)处的稳定定点。重要的是不要尝试完全检测(0,0),因为解决方案可能永远不会到达那一点。您可以使用小容差。但是,根据您的系统,更改参数后,选择此容差可能会影响行为。您还可以考虑将此问题重新表述为边界值问题。我不知道你正在尝试用这个系统做什么,所以我不能说太多其他的东西(这可能是这个网站的主题)。