persistent variable precludes simbiology acceleration, how can I keep an array available in memory
1 vue (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Jim Bosley
le 31 Mar 2018
Commenté : Jim Bosley
le 15 Mai 2018
In a simbiology model, I use a spline function in a matlab .m function to set the value of a variable parameter. For example, the assignment rule might be: glucose = forced_glucose(time) The function is called a lot, and I'd like to minimize overhead. The data for the spline is in an xlsx file, and I'd like the function to only read the file once, and then retain the data in memory until I clear the function. Using the following works very well when one is running the model and developing stuff and testing constructs:
function glu = forced_glu(time)
persistent pp
if isempty(pp)
raw = xlsread('my data file.xlsx')
pp = spline(raw(:,1),raw(:,2));
end
glu = ppval(pp,time);
end
Unfortunately, when one uses sbiofit, a warning is flagged noting that the model could not be accelerated. Apparently this is a limitation in the accelerate function, and is not surmountable. The limitation IS noted in the documentation set for "accelerate" where one is warned not to use persistent variables in functions used by simbiology, but there is no warning in the docs for "persistent".
I've been goofing around a bit trying to see if the global construct would work. There were a few glitches in my approach. I thought that someone might have run into this. Is there a way to ensure that a function used in simbiology rate expressions has a way to initialize on the first call, and to keep a structure (the piecewise polynomial structure 'pp') in accessible memory while running the model? I really don't want to process date into splines every call (several calls per time point).
In MATLAB, I could make the function use the pp as both an input and an output argument. But would that work with SB repeat assignment rules? Can I say [simbio_parameter_value pp] = forced_glucose(time,pp), and have the output pp stored in matlab memory?
Ideas? Thanks!
0 commentaires
Réponse acceptée
Arthur Goldsipe
le 2 Avr 2018
This is a timely question. The note about persistent variables being incompatible with acceleration is incorrect. (I think that used to be a limitation?) I do still encourage you to use them with caution, but pre-loading data for interpolation is a perfectly valid use of persistent variables. And I was already working with my doc writer to clarify this information and add an example of interpolation.
The most up-to-date information on what functions and language features that are supported can be found here. xlsread is not listed, so I didn't think it was supported. Your comments suggest it's supported, but I can't reproduce that on my Mac. To be safe, I suggest using the load command instead. We do document the limitations you're seeing with spline here.
I definitely recommend using a persistent variable rather than a global variable and using load instead of xlsread. I suggesting writing a separate helper function that loads the data using xlsread, creates a piecewise polynomial, and then saves it to the MAT file that you load into the persistent variable.
Finally, if you are able to reproduce the crash, please reach out. That's definitely something we would want to fix ASAP.
Plus de réponses (3)
Jim Bosley
le 2 Avr 2018
Modifié(e) : Jim Bosley
le 2 Avr 2018
1 commentaire
Arthur Goldsipe
le 2 Avr 2018
Sorry for the confusion... The documentation is incorrect. I can confirm that persistent variables are supported. We only discovered this documentation bug fairly recently, so we have not had time to correct it.
That said, code generation does require you to use all your variables (including persistent variables) more carefully than when writing general MATLAB functions. This was my first time trying to use piecewise polynomials with code generation, so it took me a while to understand the documented constraints. Maybe the easiest way to help you is to give you an example function that is compatible with sbioaccelerate:
function y = myFun(time)
persistent pp
if isempty(pp)
loaded = load('myData','breaks','coefs');
pp = mkpp(loaded.breaks, loaded.coefs);
end
y = ppval(pp, time);
end
You just need to use unmkpp to create the variables breaks and coefs from a piecewise polynomial. Then, save those variables to a MAT file. I've attached the one I used for testing this functionality.
Voir également
Catégories
En savoir plus sur Import Data dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!