我有一个常微分方程系统,我想要解决,但有一个棘手的部分,当系统达到稳定状态时,我想改变一个(或多个)参数的值。例如,考虑以下内容:
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的值将始终为零。但是如果我把这个if条件放在ODE表达式之后,If条件将不会用来纠正ODE表达式。
谢谢!
发布于 2016-04-19 22:02:04
假设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),因为解决方案可能永远不会达到那个点。您可以改为使用小公差。但是,根据系统的不同,选择此公差可能会影响更改参数后的行为。您还可以考虑将此问题重新表述为边值问题。我不知道你想用这个系统做什么,所以我不能说太多(这可能会偏离这个网站的话题)。
https://stackoverflow.com/questions/36677683
复制相似问题