Main Content

常见 ODE 问题疑难解答

本主题描述在使用求解器函数(ode45ode15s 等)求解 ODE 时可能遇到的常见问题解答。

误差容限

疑问或问题回答

如何选择误差阈值 RelTolAbsTol

RelTol 为相对精度容差,用于控制计算答案中的正确位数。AbsTol 为绝对误差容限,用于控制计算答案与实际解之间的差异。在每个步长中,解分量 i 中的误差 e 将满足

|e(i)| ≤ max(RelTol*abs(y(i)),AbsTol(i))

粗略地讲,这意味着您希望 RelTol 更正所有解分量中的位数(但小于阈值 AbsTol(i) 的解分量除外)。当分量 y(i) 非常小时,即使您对此分量不感兴趣,您仍必须指定足够小的 AbsTol(i) 值,以便获取 y(i) 中的某些正确位数,从而准确计算您更感兴趣的分量。

我希望求得达到计算机精度的答案。为什么不能直接将 RelTol 设为 eps

可以接近计算机精度,但不能如此接近。求解器不允许 RelTol 接近 eps,因为它们会尝试求连续函数的近似值。当容差与 eps 相当时,计算机的计算会导致所有函数看似不连续。

我如何通知求解器我并不在乎如何获取某个解分量的正确答案?

可以增大与此解分量相对应的绝对误差容限 AbsTol。如果容差大于此解分量,这表明不需要更正该分量中的任何位数。求解器可能必须获取此分量中的某些正确位数才能准确计算其他分量,但它通常会自动处理此过程。

问题规模

疑问或问题回答

使用 ODE 套件能够解算多大的问题?

主要限制在于内存和时间。在每个时间步长中,适用于非刚性问题的求解器分配长度为 n 的向量,其中 n 为方程组中的方程数。适用于刚性问题的求解器分配长度为 n 的向量,但还会分配一个 n×n 雅可比矩阵。对于这些求解器而言,使用 odesetJPattern 选项来指定雅可比稀疏模式可能更为有利。

如果问题是非刚性问题,或者使用的是 JPattern 选项,则可以解算具有上千个未知数的问题。但是,此种情况下,存储结果可能会带来问题。要求求解器仅在特定点求解,或者调用没有任何输出参量的求解器并使用输出函数来监控解。

我解算的方程组非常大,但是我仅关心其中几个 y 分量。是否有任何方法可避免存储所有元素?

有。OutputFcn 选项专门用于此用途。当调用没有输出参量的求解器时,求解器不会分配存储来保存所有历史解,而会在每个时间步长中调用 OutputFcn(t,y,flag)。要保留特定元素的历史解,请编写用于仅存储或绘制所关注的元素的输出函数。

启动积分有哪些成本,如何减少启动成本?

当求解器尝试查找适用于问题标量的步长时,会带来最大的启动成本。如果您碰巧知道适当的步长,请使用 InitialStep 选项。例如,如果您在事件查找循环中重复调用积分器,则在此事件之前采用的最后一个步长可能已正确缩放,以用于后续积分。键入 edit ballode 以查看示例。

积分器采用的第一个步长太大,并且错过重要行为。

使用 InitialStep 选项可以指定第一个步长。积分器尝试使用此步长,然后在必要时缩小它。

解分量

疑问或问题回答

解似乎与我的预期不符。

如果您的预期是正确的,则从默认值开始减小误差容限。需要较小的相对误差容限才能正确解算在“较长”区间积分的问题,以及不稳定性适中的问题。

检查是否存在在某段时间内小于其绝对误差容限的解分量。如果是这种情况,则表明您对这些分量中的正确位数未做任何要求。对于这些分量而言,这可能是可接受的,但无法精确计算这些分量可能会降低依赖于这些分量的其他分量的精度。

我的绘图不够平滑。

增大求解器中 Refine 的默认值:ode45 中原来的默认值为 4ode78ode89 中原来的默认值为 8,其他求解器中原来的默认值为 1Refine 的值越大,求解器生成的输出点越多。从默认值增大 Refine 值对执行速度影响不大。

我在计算解时绘制解,此解看似正常,但代码在某个点出现问题。

首先验证 ODE 函数在出现问题的位置附近是否平滑。如果不平滑,则求解器必须采用较小步长才能解决此问题。将积分区间分解为多个片段,使 ODE 函数在其上显示为平滑函数,可能会有帮助。

如果此函数非常平滑,并且代码采用极小的步长,则您可以尝试用非专用于刚性问题的求解器来解算刚性问题。改用刚性求解器 ode15sode23sode23tode23tb 中的一个。

如果我有最终值但没有初始值,应该怎么办?

ODE 套件的所有求解器都允许您按时间向前或向后解算。这些求解器的语法为 [t,y] = ode45(odefun,[t0 tf],y0);,此语法接受 t0 > tf

我的积分过程异常缓慢,使用了太多的时间步。

首先,检查并确保 tspan 不是太长。请记住,求解器使用多个必要的时间点来生成平滑的解。如果 ODE 函数在相比 tspan 非常短的时间标量上发生变化,则求解器会使用大量时间步长。长时间的积分是一个非常复杂的问题。请将 tspan 划分多个较小的片段。

如果 ODE 函数在 tspan 区间中没有发生明显变化,则可能是因为问题是刚性问题所致。尝试使用刚性求解器 ode15sode23sode23tode23tb 中的一个。

最后,确保以有效方式编写 ODE 函数。求解器会在 ODE 函数中多次计算导数。数值积分的成本在很大程度上依赖于计算 ODE 函数的成本。请不要在每次计算中重新计算复杂的常量参数,而应将其存储到全局变量中,或者对这些参数仅计算一次并将其传递给嵌套函数。

我确定解在 t 时刻 (t0 <= t <= tf ) 发生了急剧变化,但积分器步已完成,并且没有“注意到”这一点。

如果您确定在 t 时刻出现急剧变化,请尝试将 tspan 区间分解为两个片段 [t0 t][t tf],并调用两次积分器或使用 odextend 继续积分。

如果微分方程具有周期性系数或解,通过将最大步长限制为此周期的长度,确保求解器不会跨越多个周期。

问题类型

求解器可否处理使用直线法离散的偏微分方程 (PDE)?

可以,因为离散生成 ODE 方程组。根据离散的情况,可能具有一种 ODE 求解器已考虑到的与质量矩阵相关的方程组形式。此方程组往往为刚性方程组。如果 PDE 为抛物线,或现象发生的时间跨度极其不同(如流体中的化学反应),即属于这种情况。在这种情况下,请使用下列四个刚性求解器中的一个:ode15sode23sode23tode23tb

如果存在多个方程,则使用 JPattern 选项来指定雅可比稀疏模式。这对解算成败可能起到决定性的作用,因为它能防止过高的计算开销。键入 edit burgersode,查看使用 JPattern 的示例。

如果方程组不是刚性方程组,或者刚性不太强,则 ode23ode45 比刚性求解器 ode15sode23sode23tode23tb 更加有效。

您可以使用 MATLAB® PDE 求解器 pdepe 直接解算一维抛物线-椭圆偏微分方程。

可否求一组示例数据的积分?

不能直接求积分。可转为通过插值或其他数据拟合方法将数据表示为函数。此函数的平滑性至关重要。样条曲线等分段多项式拟合看似平滑,但对求解器而言却并非如此;当拟合导数包含曲折时,求解器采用较小的步长。请使用平滑的函数来表示数据,或者使用对平滑性不太敏感的某个低阶求解器(ode23ode23sode23tode23tb)。有关示例,请参阅带有时间依赖项的 ODE

另请参阅

| | |

相关主题