Using 'time' in observable expressions
조회 수: 4 (최근 30일)
이전 댓글 표시
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
채택된 답변
Florian Augustin
2022년 2월 3일
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
Arthur Goldsipe
2022년 4월 26일
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.
추가 답변 (0개)
커뮤니티
더 많은 답변 보기: SimBiology Community
참고 항목
카테고리
Help Center 및 File Exchange에서 Scan Parameter Ranges에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!