Is there a way to avoid repeating time-consuming calculations from odefun in the events function?

6 ビュー (過去 30 日間)
The right-hand side in my ODE is quite time-consuming. In the course of calculating dy/dt I calculate a variable u that I also use in my events function. Is there a way to do the time-consuming calculations only once at each time step?
Example, where I have replaced the time-consuming calculation with a simple one:
function event_example
opt = odeset('events',@stopfun);
y0 = 1;
[t,y] = ode45(@rhs,[0,3],y0,opt);
plot(t,y)
end
function [dydt,eventvalue] = time_consuming_fun(y)
% a lot of calculations to find variable u, here simplified to:
u = y;
eventvalue = u;
dydt = -u*y;
end
function dydt = rhs(~,y)
dydt = time_consuming_fun(y);
end
function [value,isterminal,direction] = stopfun(~,y)
[~,eventvalue] = time_consuming_fun(y);
value = eventvalue-0.4;
isterminal = 1;
direction = 0;
end

採用された回答

Stephen23
Stephen23 2019 年 10 月 7 日
編集済み: Stephen23 2019 年 10 月 7 日
"Is there a way to do the time-consuming calculations only once at each time step?"
Not really, because numeric ODE solvers do not call the function at specific time points, as the ode45 documentation makes clear: "However, the solver does not step precisely to each point specified in tspan. Instead, the solver uses its own internal steps to compute the solution, then evaluates the solution at the requested points in tspan". So even if you "precalculated" the values at particular timepoints, they would not be used by the solver, because the solver picks its own arbitrary timepoints to use... which there is no trivial way to predict.
You might be able to use interpolation though, depending on the behavior of the function and if it really is slow enough to justify doing: evaluate the actual ode function at the timepoints before calling ode45, pass that data as extra parameter/s, then interpolate it within an anonymous/nested function.
I doubt that memoize would make much difference, as very few function evaluations are likely to repeat exactly the same input values.
  1 件のコメント
Are Mjaavatten
Are Mjaavatten 2019 年 10 月 8 日
編集済み: Are Mjaavatten 2019 年 10 月 8 日
I was relatively sure that there was no easy solution. I submitted the question in the hope that some clever person out there might prove me wrong. Your answer strengthens my suspicion that no such solution exists. Precalculation and interpolation is an interesting idea that may work in simple cases. However, it is unlikely to work in my real problem, where y is a five component vector.
I guess I just have to accept that my problem takes about twice the time it would "ideally" take.

サインインしてコメントする。

その他の回答 (1 件)

Daniel M
Daniel M 2019 年 10 月 7 日
You might find this comment by Walter Roberson useful, where he talks about using memoize().

カテゴリ

Help Center および File ExchangeProgramming についてさらに検索

タグ

製品


リリース

R2014b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by