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

Matlab 如何为ode解算器中的每个时间步使用一个矩阵值,matlab,ode,differential-equations,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 =

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

  • y
    t
    的函数,而不是
    x
    的函数
  • 根据上述等式,除非您首先定义
    x
    值,
    y
    将是一个
    t
    x
    的功能

  • 另外
    ode45
    只返回双值,不返回函数y本身 但是它是在不同的t上进行评估的

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

  • 接下来,只需设置一个给定的
    x
    ,并评估函数。功能 评估给出结构数据类型,主要字段为
    x
    y
    <代码>x 是你的
    t
    ,而y仍然是你的
    y

  • y
    t
    的函数,而不是
    x
    的函数
  • 根据上述等式,除非您首先定义
    x
    值,
    y
    将是一个
    t
    x
    的功能

  • 另外
    ode45
    只返回双值,不返回函数y本身 但是它是在不同的t上进行评估的

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

  • 接下来,只需设置一个给定的
    x
    ,并评估函数。功能 评估给出结构数据类型,主要字段为
    x
    y
    <代码>x 是你的
    t
    ,而y仍然是你的
    y


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


与所有其他matlab ODE解算器(无特定选项?)一样,解算器
ode45
,具有可变步长,可自动适应问题和当前状态。此外,在每个步骤中,传递的右侧ODE函数将被计算多次。此外,步长调节器取决于右侧函数高阶的平滑度,非平滑轨迹会导致步长大幅减小,并且可能从同一当前状态多次重新启动,这与您的假设进一步矛盾

因此,即使你成功地实现了你的想法,你也在给你的函数添加基本上随机的噪声,使解算器变得无用,因为基本假设被违反了。即使产生了一个结果,它也几乎与你想要实现的目标无关


实现类似于您想要生成的内容的最快方法是确定
x
值关联的时间,并使用一些插值函数,零阶保持或线性插值,以在可变时间获得正确的值


用于使用平滑右侧解算每个段,更改每个段的常数
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

(请始终考虑使用选项机制来设置成本化的、特定于问题的误差容差。)

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


与所有其他matlab ODE解算器(无特定选项?)一样,解算器
ode45
,具有可变步长,可自动适应问题和当前状态。此外,在每个步骤中,传递的右侧ODE函数将被计算多次。此外,步长调节器取决于右侧函数高阶的平滑度,非平滑轨迹会导致步长大幅减小,并且可能从同一当前状态多次重新启动,这与您的假设进一步矛盾

因此,即使你成功地实现了你的想法,你也在给你的函数添加基本上随机的噪声,使解算器变得无用,因为基本假设被违反了。即使产生了一个结果,它也几乎与你想要实现的目标无关


实现类似于您想要生成的内容的最快方法是确定
x
值关联的时间,并使用一些插值函数,零阶保持或线性插值,以在可变时间获得正确的值


用于使用平滑右侧解算每个段,更改每个段的常数
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

(始终考虑使用选项机制来设置成本化、特定于问题的错误容差。)

此问题与最近发布的另一个问题非常相似:。请查看解决方案是否正确