如何在 ode 求解器中为每个时间步使用矩阵的一个值

How to use one value of a matrix for each time step inside ode solver

我有一个长度为 N 的向量 x,我想用它的值来求解微分方程:dy/dt = x - 4*y。对于每一步,我都希望 ode 求解器函数使用向量的一个值,然后在下一步中使用矩阵的下一个值。

我尝试通过将向量声明为全局变量并在 ode 求解器中像这样使用它来这样做:

global x
tspan = 0:0.01:10;
[t,filter_coef] = ode45(@ode_filter,tspan,0);

求解函数如下:

function dx = ode_filter(t,fil)

    global x 
    dx = x - 4*fil(1);

end

产生以下错误

ODE_FILTER returns a vector of length 1002, but the length of initial conditions vector is 1. The vector returned by
ODE_FILTER and the initial conditions vector must have the same number of elements.

  • yt 的函数,不是 x 的函数。
  • 从上面的等式中,除非您先定义 x 值,否则 y 将是 tx.

  • 的函数
  • ode45 return只有双值,不是函数y本身 但是它是在不同时间的评估

  • 可以做的是定义一个抛出给定未知数的函数 值 xode45。然后就得到了我上面推导的函数

  • 下一步只需设置给定的 x 并计算函数。功能 评估给出结构数据类型,主要字段是 xyx 是你的 t 而 y 仍然是你的 y

    global x
    tspan = 0:0.01:10;
    f = @(x)ode45(@ode_filter, tspan,0);
    %% Set x Value First
    x = 2;
    var = f(x);
    t = var.x;
    y = var.y;

您的方法可能基于您对显式欧拉方法的理解。如果是这种情况,您最好通过实施(指数)显式 Euler 方法。


求解器 ode45,因为所有其他 matlab ODE 求解器(没有特定选项?)具有自动适应问题和当前状态的可变步长。此外,在每个步骤中,都会多次计算传递的右侧 ODE 函数。此外,步长调节器取决于右侧函数高阶的平滑度,non-smooth 基因座导致步长急剧减小,并可能从同一当前状态多次重启,进一步与您的假设相矛盾。

因此,即使您成功实现了您的想法,您实际上也是在为您的函数添加随机噪声,导致求解器无法使用,因为违反了基本假设。就算出了结果,也和你想达到的目的几乎没有关系。


实现您想要生成的东西的最快方法是确定 x 值关联的时间,并使用一些插值函数、零阶保持或线性插值来获得在可变时间的正确值。


使用 solution extension 使用平滑的右侧求解每个线段,更改每个线段 [ tx(k), tx(k+1) ] 的常量 x(k)。定义函数有参数,避免global变量

的麻烦
function dy = ode_filter(t,y,x)
    dy = x - 4*y;
end

然后为第一个段调用积分器进行初始化,然后为所有剩余的段使用它们的常量和段结束调用积分器。

sol = ode45(@(t,y)ode_filter(t,y,x(1)), [ tx(1) tx(2) ], y0)
for k in 2:N
    sol = odextend(sol,@(t,y)ode_filter(t,y,x(k)),tx(k+1));
end

(始终考虑使用选项机制来设置自定义的、特定于问题的错误容忍度。)