Tracking max value during simulation
10 次查看(过去 30 天)
显示 更早的评论
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
0 个评论
采纳的回答
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
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.
更多回答(0 个)
社区
更多回答在 SimBiology Community
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Extend Modeling Environment 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!