我有一套以矩阵形式写成的颂歌作为$ X'= AX $;我还有一个所需的状态值$ X_des $。 $ X $是一个五维向量。我希望在所有状态达到所需值后(或至少接近$ 1e {-3} $)停止整合。如何在matlab中使用事件函数来执行此操作? (我所看到的所有帮助都是关于1维状态)
PS:我确信所有州都会在很长一段时间内接近他们想要的价值观。我只是想在符合期望值的$ 1e {-3} $之后停止整合。答案 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
的数值方法也是可能的,并且可能更具可扩展性。