Matlab ode 求解器:改变状态和指定时间 [英] Matlab ode solvers: changing state and specified time

查看:33
本文介绍了Matlab ode 求解器:改变状态和指定时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 t=0 处求解一组 ODE (dy/dt),所有初始条件 t=0 y_0=(0,0,0).我可以在不同时间为 y 值添加一些数字(例如,在 t=10 时,应将 y1 添加到该数字;在 t=20 时,应将 y2 添加到该数字等)并求解方程?

I am solving a set of ODEs (dy/dt) at t=0, all initial conditions t=0 y_0=(0,0,0). Can I add some number to the y values at different times (e.g., at t=10, y1 should be added to that number; at t=20, y2 should be added to that number, etc.) and solve the equations?

推荐答案

按照您建议的方式(以及@macduff 说明的方式)在 ODE 中插入大的不连续性会导致精度降低和计算时间延长(尤其是使用 <代码>ode45 - ode15s 可能是更好的选择,或者至少确保您的绝对和相对容差是合适的).您已经有效地创建了一个非常僵硬系统.如果您想在特定时间开始向 ODE 添加一些数字,请记住,求解器仅在其自己选择的特定时间点计算这些方程.(不要被这样一个事实误导,您可以通过将 tspan 指定为两个以上的元素来获得固定步长的输出——所有 Matlab 的求解器都是可变步长求解器,并根据它们的真实步长选择关于错误标准.)

Inserting large discontinuities in your ODE in the way you suggest (and the way illustrated by @macduff) can lead to less precision and longer computation times (especially with ode45 - ode15s might be a better option or at least make sure that your absolute and relative tolerances are suitable). You've effectively produced a very stiff system. If you want to add some number to the ODEs starting at a specific time keep in mind that the solver only evaluates these equations at specific points in time of its own choosing. (Don't be mislead by the fact that you can obtain fixed step-size outputs by specifying tspan as more than two elements – all of Matlab's solvers are variable step-size solvers and choose their true steps based on error criteria.)

更好的选择是分段集成系统并将每次运行的结果输出附加在一起:

A better option is to integrate the system piecewise and append the resultant outputs from each run together:

% t = 0 to t = 10, pass parameter a = 0 to add to ODEs
a = 0;
tspan = [0 10];
[T,Y] = ode45(@(t,y)myfun(t,y,a),tspan,y_0);

% t = 10 to t = 20, pass parameter a = 10 to add to ODEs
a = 10;
[t,y] = ode45(@(t,y)myfun(t,y,a),tspan+T(end),Y(end,:));
T = [T;t(2:end)];
Y = [Y;y(2:end,:)];

% t = 20 to t = 30, pass parameter a = 20 to add to ODEs
a = 20;
[t,y] = ode45(@(t,y)myfun(t,y,a),tspan+T(end),Y(end,:));
T = [T;t(2:end)];
Y = [Y;y(2:end,:)];

Matlab 编辑器可能会抱怨数组 TY 没有被预分配和/或增长,但在这种情况下很好,因为它们以大块的形式增长只有几次.或者,如果您想要固定的输出步长,您可以这样做:

The Matlab editor may complain about the array T and Y not being preallocated and/or growing, but it's fine in this case as they're growing in large chunks only a few times. Alternatively, if you want fixed output step-sizes, you can do this:

dt = 0.01;
T = 0:dt:30;
Y = zeros(length(T),length(y_0));

% t = 0 to t = 10, pass parameter a = 0 to add to ODEs
a = 0;
[~,Y(1:10/dt+1,:)] = ode45(@(t,y)myfun(t,y,a),T(1:10/dt+1),y_0);

% t = 10 to t = 20, pass parameter a = 10 to add to ODEs
a = 10;
[~,Y(10/dt+1:20/dt+1,:)] = ode45(@(t,y)myfun(t,y,a),T(10/dt+1:20/dt+1),Y(10/dt+1,:));

% t = 20 to t = 30, pass parameter a = 20 to add to ODEs
a = 20;
[~,Y(20/dt+1:end,:)] = ode45(@(t,y)myfun(t,y,a),T(20/dt+1:end),Y(20/dt+1,:));

如果需要,可以轻松地将上述两个代码块转换为更紧凑的 for 循环.

One could easily convert both of the above blocks of code to more compact for loops if desired.

在这两种情况下,您的 ODE 函数 myfun 以这种方式合并参数 a:

In both cases your ODE function myfun incorporates the parameter a this way:

function ydot = myfun(t,y,a)
    y(1) = ... % add a however you like
    ...

这篇关于Matlab ode 求解器:改变状态和指定时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆