Passing time step from ODE solver (ode23tb) to ODE function

조회 수: 7 (최근 30일)
Zhiren
Zhiren 2021년 2월 27일
댓글: Zhiren 2021년 2월 27일
I am currently utilizing MATLAB's ODE solver ode23tb to advance a system of equations with the structure:
[t, X] = ode23tb(@myfun, [t1 t2], X0)
With the ODE system defined as:
function dxdt = myfun(t, x)
% Some operations to figure out the time rate of x based on current values of x, stored ultimately in a variable 'blah'
dxdt = blah;
end
Here is the catch. The evaluation of 'blah' depends on all previous steps taken. (My governing equation involves fractional derivative, which fundamentally has a convolution integral ... without getting into too much detail.) Therefore I need to find an array of the successful steps taken by ode23tb.
So far, the only way I have been able to make this work is to create a modified version of ode23tb and globalize tout. (I also had to place a copy of the private function folder in the local directory.) By checking tout inside myfun, I can get a list of the steps that ode23tb stored as time history of the ODE advancement.
However, declaring global variable is obviously a bad practice. I also need to do parameter sweep eventually and run myfun multiple times with different input parameters. Yet, the global declaration creates a mess that can only be cleaned with the horrible clear all command -- which makes it challenging to run parameter sweep with a loop structure.
What would be the proper way to retrieve the tout information from ode23tb without generating a monster comprised of global and clear all?
Thanks in advance for the useful feedbacks!
  댓글 수: 1
Zhiren
Zhiren 2021년 2월 27일
Right after posting the question, I came up with a weird method: saving the variable 'tout' in an intermediate .mat file whenever ode23tb gets new step and then loading it every time myfun needs 'tout'.
Pretty sure this is not the best way to do this. Looking forward to further improving my approach!

댓글을 달려면 로그인하십시오.

채택된 답변

Jan
Jan 2021년 2월 27일
You can use the OutputFcn to store the successful steps in a persitent variable, which can be forwarded to the function to bbe integrated. This is ways faster than writing to disk.
function status = myOutputFcn(t,y,flag)
persistent T_local, T_count
switch char(flag)
case ''
T_count = T_count + 1;
if T_count > numel(T_local)
T_local(T_count + 1000) = 0;
end
T_local(t_count) = t;
status = 0;
case {'init', 'done'}
T_local = zeros(1, 1000);
T_count = 0;
status = 0;
case 'get'
status = T_local(1:T_count);
end
end
Now the funciton to be integrated cann call:
formerT = myOutputFcn([], [], 'get')
  댓글 수: 1
Zhiren
Zhiren 2021년 2월 27일
This is clever. Thanks!
My saving to disk approach indeed slowed down the process quite significantly. Glad to find a faster alternative -- and so promptly!

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Steven Lord
Steven Lord 2021년 2월 27일
The evaluation of 'blah' depends on all previous steps taken.
That sounds like you don't have an ordinary differential equation but a delay differential equation. In that case look at dde23.
  댓글 수: 1
Zhiren
Zhiren 2021년 2월 27일
Oh interesting. I am actually unfamiliar with the concept of DDE. Will certainly look into that. Thanks for the pointer!

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Ordinary Differential Equations에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by