最近,我正在利用ode45
以及求解器来找到由拉格朗日方法开发的动态方程组(微分方程)的数值解。ode23s
ode15s
Matlab
但是,即使我已经运行了ode45
长达 8 个小时的程序,我也很难得到结果。在此过程中不会出现错误,同时显示“忙碌”。我怀疑系统很僵硬,因此我试图通过ode23s
and来解决它ode15s
。但是,它仍然保持忙碌。
我该如何处理这个问题?有哪位高手能给我一些建议吗?或者我可以使用哪些其他方法来求解由拉格朗日方法导出的动态方程?
谢谢。
最近,我正在利用ode45
以及求解器来找到由拉格朗日方法开发的动态方程组(微分方程)的数值解。ode23s
ode15s
Matlab
但是,即使我已经运行了ode45
长达 8 个小时的程序,我也很难得到结果。在此过程中不会出现错误,同时显示“忙碌”。我怀疑系统很僵硬,因此我试图通过ode23s
and来解决它ode15s
。但是,它仍然保持忙碌。
我该如何处理这个问题?有哪位高手能给我一些建议吗?或者我可以使用哪些其他方法来求解由拉格朗日方法导出的动态方程?
谢谢。
您似乎认为 matlab 积分器是问题所在,根据这个假设,您应该尝试不同的积分器。但在你这样做之前,我认为检查是否确实如此是有用的。例如,可能是您的用户提供的函数挂起。或者它只是很慢。或者它会产生错误的结果。作为程序员,我们总是倾向于相信我们自己的代码是正确的,但经验表明,大多数情况下这是不正确的,事实上,外部代码经过了很好的测试,而有问题的是我们自己的代码。
使用传递给 ode45 的函数来测试这一点的一种方法是运行手写的正向或反向 Euler 方法的几次迭代。这可能需要 10 行代码。然后做 1000 个时间步并验证它应该在基本上不重要的时间内完成。如果确实需要大量时间,那么您已经缩小了问题的范围。当您进行此操作时,请通过 matlab 绘制它们来验证您在前几个时间步骤中获得的轨迹看起来是否合理。等等。
从您的问题和您之前发布的源代码来看,我猜如果您长时间积分,使用辛积分器可能会使您受益,因为听起来您正在求解的方程来自力学。辛积分器旨在积分哈密顿系统;我不知道它们是否适用于拉格朗日力学。另外,我不是这个主题的专家;我对这个建议的唯一来源是 Petzold 和 Ascher 的书。Arnold Neumaier 和 Pedro 提出的建议也是不错的起点。
MATLAB 不包含内置的辛积分器,因此如果您决定使用一个,您必须找到一个用 MATLAB 编写的您信任的软件,或者用另一种语言实现您的问题(正如 Arnold Neumaier 建议的那样)。
您的源代码似乎表明您有 10 个状态变量,从我从您的代码中可以看出的一点点,对于 10 个状态变量的问题,右侧函数评估非常复杂(例如,与我的示例相比)我们在 ODE 文献中看到过,它们往往很简单)。我的猜测(没有执行您的代码)是右侧评估花费的时间不可忽略;这个猜测可以通过分析代码来测试,尽管 MATLAB 的分析器并不总是最可靠的(例如,参见Abandon MATLAB 上的这篇文章),并且探查器可能并不总是提供准确的信息(采样探查器应该比检测探查器产生更准确的信息)。如果分析器似乎对您没有多大帮助(即,它不能很好地说明为什么您的程序需要这么长时间),您可以尝试“随机暂停”(请参阅Mike Dunlavey 在 SciComp 上的这篇文章)。我不知道如何在 MATLAB 中实现它,确切地说,所以希望你不需要诉诸这种策略。
从您编写代码的方式来看,它的编写方式似乎很容易出错(可能不是),并且可能值得通过调试器或单元测试来检查您的代码. 我强烈建议以一种让其他人更容易阅读的方式编写你的代码,只要它更容易调试,从而更容易排除拼写错误作为可能的错误来源,这样就很清楚数字方法是导致您观察到的问题的主要问题。
您可以尝试用不同语言编写的求解器。
在 Matlab 中,您可以让代码打印一些东西(参见帮助 odeprint),然后调查输出。或者添加选项(帮助 odeset),或者缩短时间间隔。
Matlab ode 求解器似乎没有时间限制选项,但您可以轻松更改源代码以在给定数量的时间步或两个 tocs 的给定 cpu 时间差后返回)。然后您可以使用分析器(帮助配置文件)检查时间的去向。
编辑:从另一条评论中,我了解到您使用了复杂的 Mathematica 生成的代码。这样的代码有时在数值上非常不稳定,这可能会导致求解器施加极小的时间步长。要检查这一点,请运行您的 matlab 代码一段越来越短的时间间隔(以 10 次方为单位),直到它最多在一分钟后返回;这将使您检查这个特定的潜在问题来源。