我有一个长度为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.
答案 0 :(得分:1)
y
是t
的功能,而不是x
的功能。根据上面的公式,除非您首先定义x
值,否则y
将是
t
和x
的功能。
还ode45
仅返回双精度值,而不返回函数y本身
但它是在不同的时间进行的评估
可以做的是定义一个引发给定未知数的函数
值x
到ode45
。然后,您将获得上面我推断的功能。
下一步只需设置一个给定的x
并评估函数。功能
评估给出结构数据类型,其主要字段为x
和y
。 x
是您的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
(始终考虑使用选项机制来设置针对问题的特定错误容忍度。)