Using 'time' in observable expressions
4 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Abed Alnaif
el 3 de Feb. de 2022
Comentada: Abed Alnaif
el 27 de Abr. de 2022
Hello,
Is it possible to select only certain timepoints for observable calculations, for example:
mdl.addobservable('maxA','max(A(time>(3*7*24)))','Units','dimensionless');
In my example, A is a parameter that is set by a repeated assignment rule.
When I run the model in R2021b, I get the following error, whih suggests incorrect dimensions (but my observable expression should return a scalar, no?):
------------------------------------------------------
When running sbiosteadystate:
Error using sbiosteadystate (line 128)
sbiosteadystate encountered a model compilation error.
Caused by:
Error using SimBiology.internal.verifyHelper
--> Error reported from Expression Validation:
The result of evaluating observable 'maxA' has the wrong size. It must either be a scalar or a column vector of the same length as the time vector.
-------------------------------------------------------
When running sbiosimulate:
Error using SimBiology.internal.simulate
--> Error reported from Expression Validation:
The result of evaluating observable 'maxA' has the wrong size. It must either be a scalar or a column vector of the same length as the time vector.
----------------------------------------------------
Please advise.
Thank you,
Abed
0 comentarios
Respuesta aceptada
Florian Augustin
el 3 de Feb. de 2022
Hi Abed,
when evaluating expressions of observables, SimBiology first tries to determine whether the result is a scalar value or a vector. I therefore recommend to write observables' expressions in a way that they either always return a scalar value or always a vector of values - for any possible input values of referenced model components and time.
In your case, the expression max(A(time > 3*7*24))) can be a vector whose length differs from the length of the time vector, e.g. if none of the values in time exceeds 3*7*24, or if the maximum is attained at multiple time points. You can write a helper function that returns the max. value and protects against invalid edge cases:
function maxValue = getMaxValueAfterSpecifiedTime(values, time, threshold)
% Get max value (call unique to ensure scalar or empty output).
maxValue = unique(max(values(time > threshold)));
% Protect against empty maxValue by returning nan.
if isempty(maxValue)
maxValue = nan;
end
end
You can then call this helper as follows:
% Load/build your model
mdl = sbmlimport("radiodecay");
% Observable referencing time point
observable = addobservable(mdl, "maxX", "getMaxValueAfterSpecifiedTime(x, time, 2)");
set(observable, "Active", true);
% Set simulation options
configset = getconfigset(mdl);
configset.RuntimeOptions.StatesToLog = "x";
% Simulate and plot model state and active observable
simData = sbiosimulate(mdl);
sbioplot(simData);
When you run this particular example, you may see that maxX differs from the actual max value as shown in the plots. You can add interpolation to your helper function to increase the accuracy of the reported max value; an example how this could look like is attached to this post.
I hope this helps.
Best,
-Florian
4 comentarios
Arthur Goldsipe
el 26 de Abr. de 2022
I just had an idea for how to avoid writing a separate function getMaxValueAfterSpecifiedTime. In many cases, I think you could instead change
max(expression)
to
max(vertcat(nan,expression))
to make sure that max is never called on an empty vector.
Más respuestas (0)
Comunidades de usuarios
Más respuestas en SimBiology Community
Ver también
Categorías
Más información sobre Scan Parameter Ranges en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!