MATLAB:在ode45中调用feval的替代方法
我希望我在这里的主题。我在这里提问,因为它在faq页面上说:一个关于(除其他外)软件算法的问题:),所以这里是: 我需要求解一个ODE系统(如$\dot x=a(t)x$。矩阵a可能会改变,并在函数调用中作为字符串给出(Calc_EDS_v2('Sys_EDS_a'),…)MATLAB:在ode45中调用feval的替代方法,matlab,loops,performance,Matlab,Loops,Performance,我希望我在这里的主题。我在这里提问,因为它在faq页面上说:一个关于(除其他外)软件算法的问题:),所以这里是: 我需要求解一个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:
然后我在循环中使用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-file.q作为起始向量返回给调用。正如你所看到的,我只是在区间[t,t+t_步]上使用ode45。这是因为我的系统矩阵A可以强制ode45使用很多步,导致它很快达到Absol或RelTol
现在我的A有点像B(t)*Q(t),所以在m文件intQ_2_v2.m中,我需要在t时计算B和Q。
我第一次是这样做的:(v1-file,所以函数名不同)
当然,这只是假设A是一个2x2矩阵。在这种设置下,一个基本系统需要10到15秒的时间来计算
我现在使用B1.m到B4.m和Q1.m到B4.m的文件(我知道这并不优雅,但我以后需要在B上使用quadgk,而quadgk不支持矩阵函数)
funcname(字符串)指的是B或Q(加上k)和d是系统的维度
现在我知道这会比第一个版本花费更多的时间,但我看到计算时间是第一个版本的十倍!(150到160秒)我知道打开4个文件并计算每个ode循环大约40次是昂贵的…而且我也不能预先计算B和Q,因为ode45使用自适应步长
有没有办法不使用最后一个循环
我最感兴趣的是一种可以缩短计算时间的解决方案。我确实觉得我错过了一些东西……但我真的无法确定。由于这一解决方案花费了将近3分钟而不是10秒,我现在可以在每次测试之间喝杯咖啡了……(请不要告诉我要一台更快的计算机)
(很抱歉问这么长的问题)我不确定自己是否完全理解您在这里做什么,但我可以提供一些提示
我希望这将使您的运行时恢复到第一个方法提供的运行时。请务必告诉我们这是否是问题所在,或者您是否找到了其他解决方案。我不确定是否完全理解您在这里所做的工作,但我可以提供一些提示
我希望这将使您的运行时恢复到第一种方法提供的运行时。请务必告诉我们这是否是问题所在,或者您是否找到了其他解决方案。非常感谢您的回答!正如您所建议的那样,我一直在使用单元格数组中的函数句柄,仅此一项就将计算时间减少了一半。此外,我还设法使用探查器来优化其他一些区域。我被迫使用全局函数,因为a)matlab中的ode解算器是预定义函数,不允许传递附加参数(afaik)和b)函数(b和Q)将来可能会更改,因此它们不应该嵌套在主文件中。再次感谢您的帮助,这是一个极好的起点!我会投赞成票,但我现在不能:-/@PingLu很高兴它有帮助。我对ODE求解不太了解,但我在Matlab中使用过很多优化器,也遇到过类似的问题。请随意接受答案!对不起,我不知道区别:)现在它被接受了。我正忙着从我的脚本中再抽出一两秒钟:D分析器真的非常有用!非常感谢你的回答!正如您所建议的,我一直在使用单元格数组中的函数句柄,仅此一项就将计算时间减少了一半。此外,我还设法使用Profiler优化了其他一些方面。我被迫使用全局函数,因为a)matlab中的ode解算器是预定义的函数,不允许传递额外的参数(afaik)和b)函数(b和Q)将来可能会更改,因此它们不应该嵌套在主文件中。再次感谢您的帮助,这是一个极好的起点!我会投赞成票,但我现在不能:-/@PingLu很高兴它有帮助。我对ODE求解不太了解,但我在Matlab中使用过很多优化器,也遇到过类似的问题。请随意接受答案!对不起,我不知道区别:)现在它被接受了。我正忙着试一试
function q=intQ_2_v1(t,X)
[..]
B(1)=...; ... B(4)=...;
Q(1)=...; ...
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
[..]