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

时间:2019-05-19 22:27:19

标签: matlab ode differential-equations

我有一个长度为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.

2 个答案:

答案 0 :(得分:1)

enter image description here

  • yt的功能,而不是x的功能。
  • 根据上面的公式,除非您首先定义x值,否则y将是 tx的功能。

  • ode45仅返回双精度值,而不返回函数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;

答案 1 :(得分:1)

您可能将您的方法基于对显式Euler方法的理解。如果是这种情况,则最好实现(指数)显式Euler方法。


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

因此,即使您成功实现了构想,也实际上向函数中添加了随机噪声,由于违反了基本假设,因此使求解器无用。即使产生了结果,它也几乎与您想要实现的目标无关。


实现类似您想要产生的结果的最快方法是确定与x值关联的时间,并使用一些插值函数(零阶保持或线性插值)来获取正确的值在不同的时间。


使用solution extension通过平滑的右侧求解每个线段,为每个线段x(k)更改常数[ tx(k), tx(k+1) ]。将函数定义为具有参数,避免麻烦的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

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