Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MATLAB:在ode45中调用feval的替代方法_Matlab_Loops_Performance - Fatal编程技术网

MATLAB:在ode45中调用feval的替代方法

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:

我希望我在这里的主题。我在这里提问,因为它在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: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秒,我现在可以在每次测试之间喝杯咖啡了……(请不要告诉我要一台更快的计算机)


(很抱歉问这么长的问题)

我不确定自己是否完全理解您在这里做什么,但我可以提供一些提示

  • 使用探查器,它将帮助您准确了解瓶颈所在

  • 使用feval比直接使用函数句柄慢,尤其是每次使用str2func生成句柄时。使用全局变量也会慢一些(除非绝对必要,否则最好避免使用这些变量)。重复使用它们时,每一个都会加起来(如图所示)。将每个MFile的函数句柄存储在单元格数组中,并将其直接传递给函数,或使用嵌套函数进行优化,以使句柄的单元格数组对正在优化的函数可见。就个人而言,我更喜欢嵌套方法,但如果您将这些MFile用于其他位置,则传递会更好


  • 我希望这将使您的运行时恢复到第一个方法提供的运行时。请务必告诉我们这是否是问题所在,或者您是否找到了其他解决方案。

    我不确定是否完全理解您在这里所做的工作,但我可以提供一些提示

  • 使用探查器,它将帮助您准确了解瓶颈所在

  • 使用feval比直接使用函数句柄慢,尤其是每次使用str2func生成句柄时。使用全局变量也会慢一些(除非绝对必要,否则最好避免使用这些变量)。重复使用它们时,每一个都会加起来(如图所示)。将每个MFile的函数句柄存储在单元格数组中,并将其直接传递给函数,或使用嵌套函数进行优化,以使句柄的单元格数组对正在优化的函数可见。就个人而言,我更喜欢嵌套方法,但如果您将这些MFile用于其他位置,则传递会更好


  • 我希望这将使您的运行时恢复到第一种方法提供的运行时。请务必告诉我们这是否是问题所在,或者您是否找到了其他解决方案。

    非常感谢您的回答!正如您所建议的那样,我一直在使用单元格数组中的函数句柄,仅此一项就将计算时间减少了一半。此外,我还设法使用探查器来优化其他一些区域。我被迫使用全局函数,因为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
    [..]