Labfans是一个针对大学生、工程师和科研工作者的技术社区。 论坛首页 | 联系我们(Contact Us)
MATLAB爱好者论坛-LabFans.com
返回   MATLAB爱好者论坛-LabFans.com > 其它 > 资料存档
资料存档 资料存档
回复
 
主题工具 显示模式
旧 2019-12-14, 20:46   #1
poster
高级会员
 
注册日期: 2019-11-21
帖子: 3,006
声望力: 66
poster 正向着好的方向发展
帖子 MATLAB:在ode45中调用feval的替代方法

我希望我在这里成为话题。我要问的是它在常见问题页面上说的:一个(除其他外)有关软件算法的问题:)

我需要解决一个ODE系统(例如$ \ dot x = A(t)x $。矩阵A可能会更改,并在函数调用中以字符串形式给出(Calc_EDS_v2('Sys_EDS_a',...)
然后我在循环中使用ode45来找到我的x:

function [intervals, testing] = EDS_calc_v2(smA,options,debug) [..] for t=t_start:t_step:t_end) [Te,Qe]=func_int(@intQ_2_v2,[t,t+t_step],q); q=Qe(end,:); [..] end [..] func_int是ode45,@ intQ_2_v2是我的m文件。 q作为开始向量返回给调用。如您所见,我只是在间隔[t,t + t_step]上使用ode45。那是因为我的系统矩阵A可以强制ode45使用很多步骤,从而使其很快达到AbsTol或RelTol。

现在我的A类似于B(t)* Q(t),因此在m文件intQ_2_v2.m中,我需要在时间t评估B和Q。我首先这样做是这样的:(v1 -file,因此函数名称不同)

function q=intQ_2_v1(t,X) [..] B(1)=...; ... B(4)=...; Q(1)=...; ... 当然,仅在假设A是2x2矩阵的情况下才可以实现上述目的。通过该设置,基本系统的计算时间大约在10到15秒之间。

我现在使用文件B1.m到B4.m和Q1.m到B4.m(我知道不是很优雅,但是稍后我需要在B上使用quadgk,并且quadgk不支持矩阵函数。 )

function q=intQ_2_v2(t,X) [..] global funcnameQ, funcnameB, d for k=1:d Q(k)=feval(str2func([funcnameQ,int2str(k)]),t); B(k)=feval(str2func([funcnameB,int2str(k)]),t); end [..] 引用B或Q(加上k)的funcname(字符串),而d是系统的维数。

现在,我知道它将比第一个版本花费更多时间,但我发现计算时间是原来的十倍! (获取150到160秒)我确实知道打开4个文件并为每个ode-loop评估大约40次是昂贵的...而且我也无法预先评估B和Q,因为ode45使用自适应步长...

有没有办法不使用最后一个循环?

通常,我对降低计算时间的解决方案很感兴趣。我确实感觉到我缺少了一些东西……但是不能真正把手指放在上面。在那一次花了将近3分钟而不是10秒的时间之后,我现在可以在每次测试之间喝杯咖啡了……(请不要告诉我要买一台更快的计算机)

(很长的问题很抱歉)



回答:

我不确定我是否完全了解您在这里做什么,但是我可以提供一些提示。
  1. 使用探查器,它将帮助您准确了解瓶颈所在。
  2. 使用feval比直接使用函数句柄慢,尤其是在每次使用str2func生成句柄时。使用全局变量也会减慢速度(除非绝对必要,否则避免这些是一个好习惯)。当重复使用它们时,它们中的每一个实际上都累加了(如下所示)。将函数句柄存储在单元数组中的每个mfile中,然后将它们直接传递给函数,或使用嵌套函数进行优化,以便对要优化的函数可见句柄的单元数组。就个人而言,我更喜欢嵌套方法,但是如果您将在其他地方使用这些mfile,则传递会更好。
我希望这会使您的运行时恢复到第一种方法所给的水平。请务必告诉我们这是否是问题所在,或者您是否找到了其他解决方案。



更多&回答...
poster 当前离线   回复时引用此帖
回复

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛禁用 表情符号
论坛启用 [IMG] 代码
论坛启用 HTML 代码



所有时间均为北京时间。现在的时间是 23:43


Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.