简体   繁体   English

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

[英]MATLAB: alternatives to calling feval in ode45

I hope I am on topic here. 我希望我在这里成为话题。 I'm asking here since it said on the faq page: a question concerning (among others) a software algorithm :) So here it goes: 我要问的是它在常见问题页面上说的:一个(除其他外)有关软件算法的问题:)

I need to solve a system of ODEs (like $ \\dot x = A(t) x$. The Matrix A may change and is given as a string in the function call (Calc_EDS_v2('Sys_EDS_a',...) 我需要解决一个ODE系统(例如$ \\ dot x = A(t)x $。矩阵A可能会更改,并在函数调用中以字符串形式给出(Calc_EDS_v2('Sys_EDS_a',...)
Then I'm using ode45 in a loop to find my x: 然后我在循环中使用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
[..]

with func_int being ode45 and @intQ_2_v2 my m-file. func_int是ode45,@ intQ_2_v2是我的m文件。 q is given back to the call as the starting vector. q作为开始向量返回给调用。 As you can see I'm just using ode45 on the intervall [t, t+t_step]. 如您所见,我只是在间隔[t,t + t_step]上使用ode45。 That's because my system matrix A can force ode45 to use a lot of steps, leading it to hit the AbsTol or RelTol very fast. 那是因为我的系统矩阵A可以强制ode45使用很多步骤,从而使其很快达到AbsTol或RelTol。

Now my A is something like B(t)*Q(t), so in the m-file intQ_2_v2.m I need to evaluate both B and Q at the times t. 现在我的A类似于B(t)* Q(t),因此在m文件intQ_2_v2.m中,我需要在时间t评估B和Q。 I first done it like so: (v1 -file, so function name is different) 我首先这样做是这样的:(v1 -file,因此函数名称不同)

function q=intQ_2_v1(t,X)  
[..] 
B(1)=...; ...   B(4)=...;
Q(1)=...; ...

than that is naturally only with the assumption that A is a 2x2 matrix. 当然,仅在假设A是2x2矩阵的情况下才可以实现上述目的。 With that setup it took a basic system somewhere between 10 and 15 seconds to compute. 通过该设置,基本系统的计算时间大约在10到15秒之间。

Instead of the above I now use the files B1.m to B4.m and Q1.m to B4.m (I know that that's not elegant, but I need to use quadgk on B later and quadgk doesn't support matrix functions.) 我现在使用文件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
[..]

funcname (string) referring to B or Q (with added k) and d is dimension of the system. 引用B或Q(加上k)的funcname(字符串),而d是系统的维数。

Now I knew that it would cost me more time than the first version but I'm seeing the computing times are ten times as high! 现在,我知道它将比第一个版本花费更多时间,但我发现计算时间是原来的十倍! (getting 150 to 160 seconds) I do understand that opening 4 files and evaluate roughly 40 times per ode-loop is costly... and I also can't pre-evalute B and Q, since ode45 uses adaptive step sizes... (获取150到160秒)我确实知道打开4个文件并为每个ode-loop评估大约40次是昂贵的...而且我也无法预先评估B和Q,因为ode45使用自适应步长...

Is there a way to not use that last loop? 有没有办法不使用最后一个循环?

Mostly I'm interested in a solution to drive down the computing times. 通常,我对降低计算时间的解决方案很感兴趣。 I do have a feeling that I'm missing something... but can't really put my finger on it. 我确实感觉到我缺少了一些东西……但是不能真正把手指放在上面。 With that one taking nearly three minutes instead of 10 seconds I can get a coffee in between each testrun now... (plz don't tell me to get a faster computer) 在那一次花了将近3分钟而不是10秒的时间之后,我现在可以在每次测试之间喝杯咖啡了……(请不要告诉我要买一台更快的计算机)

(sorry for such a long question ) (很长的问题很抱歉)

I'm not sure that I fully understand what you're doing here, but I can offer a few tips. 我不确定我是否完全了解您在这里做什么,但是我可以提供一些提示。

  1. Use the profiler, it will help you understand exactly where the bottlenecks are. 使用探查器,它将帮助您准确了解瓶颈所在。

  2. Using feval is slower than using function handles directly, especially when using str2func to build the handle each time. 使用feval比直接使用函数句柄慢,尤其是在每次使用str2func生成句柄时。 There is also a slowdown from using the global variables (and it's a good habit to avoid these unless absolutely necessary). 使用全局变量也会减慢速度(除非绝对必要,否则避免这些是一个好习惯)。 Each of these really adds up when using them repeatedly (as it looks like here). 当重复使用它们时,它们中的每一个实际上都累加了(如下所示)。 Store function handles to each of your mfiles in a cell array and either pass them directly to the function or use nested function for the optimization so that the cell array of handles is visible to the function being optimized. 将函数句柄存储在单元数组中的每个mfile中,然后将它们直接传递给函数,或使用嵌套函数进行优化,以便对要优化的函数可见句柄的单元数组。 Personally, I prefer the nested method, but passing is better if you will use those mfiles elsewhere. 就个人而言,我更喜欢嵌套方法,但是如果您将在其他地方使用这些mfile,则传递会更好。

I expect this will get your runtime back to close to what the first method gave. 我希望这会使您的运行时恢复到第一种方法所给的水平。 Be sure to tell us if this was the problem or if you found another solution. 请务必告诉我们这是否是问题所在,或者您是否找到了其他解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM