在matlab ode45中使用事件函数进行多维状态向量

时间:2014-04-02 17:19:00

标签: matlab events ode

我有一套以矩阵形式写成的颂歌作为$ X'= AX $;我还有一个所需的状态值$ X_des $。 $ X $是一个五维向量。我希望在所有状态达到所需值后(或至少接近$ 1e {-3} $)停止整合。如何在matlab中使用事件函数来执行此操作? (我所看到的所有帮助都是关于1维状态)

PS:我确信所有州都会在很长一段时间内接近他们想要的价值观。我只是想在符合期望值的$ 1e {-3} $之后停止整合。

1 个答案:

答案 0 :(得分:0)

首先,我假设您已经意识到可以使用matrix exponential(Matlab中的expm)来直接求解线性微分方程组。

有很多方法可以完成你想要做的事情。它们都依赖于您的系统,它的行为方式以及您想要捕获的特定事件。这是2乘2线性微分方程组的一个小例子:

function multipleeventsdemo
A = [-1 1;1 -2]; % Example A matrix
tspan = [0 50];  % Initial and final time
x0 = [1;1];      % Initial conditions
f = @(t,y)A*y;   % ODE function
thresh = 0;      % Threshold value
tol = 1e-3;      % Tolerance on threshold

opts = odeset('Events',@(t,y)events(t,y,thresh,tol)); % Create events function
[t,y] = ode45(f,tspan,x0,opts);                       % Integrate with options
figure;
plot(t,y);

function [value,isterminal,direction] = events(t,y,thresh,tol)
value = y-thresh-tol;
isterminal = all(y-thresh-tol<=0)+zeros(size(y)); % Change termination condition
direction = -1;

当两个状态都在tol thresh范围内时,停止集成。这是通过调整事件函数的isterminal输出来完成的。请注意,单独的容差和阈值变量并不是必需的 - 您只需要定义交叉值。

如果你的系统在接近它的稳定状态时振荡(如果A具有复杂的特征值),那么你需要做更多的工作。但你的问题并没有表明这一点。再次,数值积分可能不是解决这类系统问题的最简单/最好的方法。以下是如何将expm与一些符号数学结合使用:

A = [-1 1;1 -2];
x0 = [1;1];
tol = 1e-3;
syms t_sym
y = simplify(expm(A*t_sym)*x0)           % Y as a function of t
t0 = NaN(1,length(x0));
for i = 1:length(x0)
    sol = double(solve(y(i)==tol,t_sym)) % Solve for t when y(i) equal to tol
    if ~isempty(sol)                     % Could be no solution, then NaN
        t0(i) = max(sol);                % Or more than one solution, take largest
    end
end
f = matlabFunction(y);                   % Create vectorized function of t
t_vec = linspace(0,max(t0),1e2);         % Time vector
figure;
plot(t_vec,f(t_vec));

但是,这仅适用于相当小的A,因为符号数学。使用expm的数值方法也是可能的,并且可能更具可扩展性。