本文摘要:(由ai生成)
在Matlab中,使用ode45等函数求解微分方程时,可以通过设置options中的OutputFcn和OutputSel参数来实时监控求解过程。OutputFcn可设为@odeplot或@odeprint来分别实时绘图或打印解,而OutputSel则用于选择性地输出特定变量的解。这种方法适用于长时间求解或需要实时监控的情况,避免了求解完成后才能查看结果的局限性。
下面我用一个自己遇到并成功解决的问题实例来带大家来学一个很有用的技巧:即用matlab求解微分方程时,如何实时输出求解结果?(想一下你每次求解微分方程时,是不是一定要等待全部求解完成才能查看求解结果?如果求解时间很长,是不是怀疑死机了?如果求解时间很长,中途你被迫中止程序,可前面运行的结果并没有保存?)
理工科的学生应该都用过matlab微分方程求解器来求某个微分方程(组)的数值解。
matlab中提供了几个很有用的函数用来求解微分方程组,例如ode23,ode45,ode15s
等等。这些函数各自针对具有不同特点的微分方程,比如刚性ode、微分代数方程等。
以最常用的ode45
为例,基本用法是:
[tt,yy]=ode45(dfun,tspan,y0,options)
其中,
dfun
是由我们的原始ode写成的一阶ode系统;odeset
指令来设置AbsTol
为很小的数即可: 仔细观察上图,可以看到options里面其实还有很多其他的设置可以自己指定,例如,虽然或许你没亲手设置过,但你一定可以猜到,里面的MaxStep
是设置求解的最大时间步长的;Events
是定义一种“事件”,当这个事件发生时,求解停止;OutputFcn
是设置输出解的数据的。利用上面的基本语法(不指定options参数)求解微分方程是最基本的用法,你必须要等待求解完成后才能在工作区间查看tt和yy解数据。但是如果你的方程很复杂,求解时间很长,你不得不忍受运行过程中除了左下角显示”在忙“而没有任何其他提示仿佛死机一般的寂静时刻;更难受的是,程序一旦运行你就不能停止,否则前面求解的结果全部白费了,因为没有保存(你始终只能在程序运行完成后才能查看解的数据)。此时,你或许会想到通过设置options来达到实时显示求解结果的目的。
幸运的是,上图options中的OutputFcn参数确实可以帮助我们实现这一点。看下帮助文档中关于OutputFcn参数的解释:意思是,我们可以设置OutputFcn为这几个内置的函数,使得我们的求解结果能按照指定的输出函数实时输出。
比如,如果我们设置:
options = odeset('OutputFcn',@odeplot)
那么运行过程中,屏幕将会实时绘制所有解的数据。
如果我们设置:
options = odeset('OutputFcn',@odeprint)
那么运行过程中,屏幕将会实时打印出所有解数据和对应的时间点数据。
这或许已经可以解决问题了,但你可能还会遇到下一个问题:如果你的微分方程组比较复杂,有几百几千个求解变量,此时如果实时绘制所有解数据,你会得到一团糟的图窗;如果每个时间点都把所有解的数据打印在窗口,也会一团乱麻。
幸好,开发者也想到了这一点,在options中提供了另外一个可设置参数OutputSel
:即自己指定哪些解是我要实时Output的。
举个例子,我设置OutputFcn
为odeprint
,设置OutputSel
为1
(我的目的:想要程序运行时,实时打印第1个解的数据和时间点)。利用程序:
options = odeset(OutputFcn',@odeprint,'OutputSel',1);
[tt,Psi]=ode15s(dpsi,tspan,psi_0,options); % dpsi是我自己的ode方程组
运行得到:
读者可以找个你自己的ode求解程序,尝试设置options中的OutputFcn
为odeplot
,设置OutputSel
为1:3
,来实现运行过程中实时绘制前3个解的数据图线。
如果你求解问题的规模确实很大,你不得不用机群来提交matlab程序。此时,”保存实时求解得到的解的数据“是一个非常非常非常有必要的需求。因为,没有人能够忍受由于自己提交的任务被意外终止致使前面几个小时的计算没有得到任何结果的不幸事件发生。
由于机群中运行程序一般没有图形化窗口,只能默认程序运行完你再save数据。因此,上述”实时绘制解的图像“或者”实时打印解的结果“显然是无法满足你的需求了。
下一篇中我会教你如何在程序运行过程中保存实时求解的数据,而不用再担心程序被终止了前面的计算白费了的情况。