Tracking max value during simulation

조회 수: 10 (최근 30일)
Abed Alnaif
Abed Alnaif 2023년 1월 26일
댓글: Abed Alnaif 2023년 1월 27일
Hello,
I'm trying to keep track of the max value of a variable during simulation. I'm currently doing this using an event, as follows:
mdl.addevent('A > maxA',{'maxA = A'})
However, this isn't working. I believe the reason it's not working is because events are only trigerred on rising edges, and thus maxA doesn't track A as A rises gradually.
Is there a way to accomplish tracking of the maximum value of a variable during a simulation? Since I am using maxA during the simulation, I cannot calculate it post-hoc (i.e., can't use an observable).
Thank you!
Abed

채택된 답변

Jeremy Huard
Jeremy Huard 2023년 1월 27일
편집: Jeremy Huard 2023년 1월 27일
Hi Abed,
the easiest way to keep track of the max of a species during a simulation might be to use an external function (see attachment) with a persistent variable that stores the current maximal value:
function out = getmax(time,s)
persistent maxS
if time==0 || isempty(maxS)
maxS = -Inf;
end
maxS = max(maxS,s);
out = maxS;
end
You can then use this function in a repeated assignment:
% Create model.
m1 = sbiomodel('test');
% Add compartment
c1 = addcompartment(m1,'comp',1);
% Add species to compartment.
addspecies(c1, 's');
% Add rule to model.
addrule(m1, 's = sin(time*2*pi + 2) + 2', 'repeatedAssignment');
% Add dummy ODE to model
addspecies(c1, 's2',10);
addrule(m1, 's2 = -s2', 'rate');
% Add parameter to model.
addparameter(m1, 'maxS',Constant=false);
addrule(m1,'maxS = getmax(time,s)','repeatedAssignment');
% Modify settings
cs = getconfigset(m1);
cs.SolverOptions.MaxStep = 0.01;
% Simulate
simfun = createSimFunction(m1,{},{'maxS','s'},[],[],AutoAccelerate=false);
stopTime = 1.5;
results = simfun([],stopTime);
sbioplot(results);
I hope this helps.
Best regards,
Jérémy
  댓글 수: 3
Arthur Goldsipe
Arthur Goldsipe 2023년 1월 27일
The persistent variable was my first thought, too. But it makes me a little nervous. (I'll say why in a moment.) So I suggest usin git with caution.
At the very least, I would validate that the solution makes sense after the fact. For example, make sure the calculated maximum approximates the real maximum of the state. And ideally check that the differential equations still seemed to be solved accurately. One relatively simple approach for doing this would be to perform repeated simulatations until your answer converges. For the first simulation and only the first simulation, use the persistent variable to calculate the maximum. From then on, replace the persistent variable calculation with a function that calculates the maximum by interpolating using the data from the previous simulation. Keep updating the data used for interpolation until it doesn't change signficantly. (If anything about that doesn't make sense, let me know.)
Here's why I'm concerned about the persistent variable approach: First, the persistent variable might end up storing trial state values that were ultimately rejected because they didn't meet error tolerances. So the "maximum" might not be the "real maximum." Second, this function now has "memory" and could return a different result for the same inputs, depending on how the function is called in between. This probably breaks some core assumptions of the ODE solver, which could in turn lead to unexpected errors or an inability to control the solution within the specified error tolerance.
Abed Alnaif
Abed Alnaif 2023년 1월 27일
Thanks for these insights Arthur. These make sense and I hadn’t considered these issues. Maybe the best approach is to devise a small ODE system which will have memory for Cmax, at least approximately, although nothing comes to mind immediately.

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

추가 답변 (0개)

커뮤니티

더 많은 답변 보기:  SimBiology Community

카테고리

Help CenterFile Exchange에서 Extend Modeling Environment에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by