Limitations
agent-based modeling, abm, bptk, bptk-py, python, business simulation
Limitations
Currently the BPTK_Py framework is geared towards our own need and has a number of limitations. We are more than happy to extend the framework to suit YOUR need, so please let us what you need so that we can prioritize our activities. You can reach us at support@transentis.com
The Rust execution engine
The Rust engine runs System Dynamics scenarios only. A scenario manager registered as agent-based ("type": "abm") always runs in Python and ignores backend, and so does the agent-based half of a hybrid model.
Running on the Rust engine means serialising the model, and four things cannot go that way:
- A System Dynamics model with agents and a user-defined function — the function could read what the agents produced. The two halves advance one step at a time, and the engine computes every step of a run at once, so such a function would read a step that has not happened yet. A model that merely has agents is fine; it is the combination that is refused.
- A user-defined function registered with
elementwise=False— it is handed a whole array and answers once, and the engine’s callback answers with one number. - A model compiled from XMILE — the compiler produces a standalone Python class, which has no serialisation at all.
- An installation without the engine — the pure-Python wheel, which is what micropip installs in a browser.
Asking for backend="rust" on a model from that list raises RustBackendError, naming which of the four it is. See Execution Backends for how to catch it.
Arrayed models are not in that list. They run on the Rust engine like any other: an arrayed element’s sub-elements are ordinary scalar elements named with brackets, the aggregations became engine-side functions over them, and dot is expanded into a sum of products before the model is handed over. User-defined functions are not in that list either: a model that has them runs on the engine, which calls back into Python at those nodes and says so at [WARN].
A stochastic model that has to be reproducible across a restart — a session externalised to Postgres or Redis and resumed later — must pass an explicit seed to begin_session(). Deterministic models resume exactly regardless.
Running the documentation in a browser
Most pages of this documentation run in your browser, on Pyodide. A page whose model is read from files beside it is shown with its results instead, because those files do not reach the browser. Pyodide is a real Python, but it is not the Python on your machine, and three limits come with it:
- The Python engine only. There is no Rust engine in the browser — the compiled extension has no place to run there.
- One kind of interaction per page load. A slider answers move after move, and a cell edit re-runs everything downstream. Doing both in one session eventually exhausts the browser’s heap and the page goes quiet until you reload it. Every plot leaves its figure behind, and the page shares one heap for everything on it.
- No progress bars.
progress_bar=Trueneeds a lock that the browser platform does not provide, and the run stops rather than slows.
None of this applies when you run the same notebook on your own machine. The Installation page shows how.
Capabilities that need an extra
The base install deliberately does not carry everything. Plotting, the XMILE compiler, the server and Logfire logging each live behind an extra, and using one without installing it raises an error naming the extra. See Installation.
Simulation and XMILE
Here are the known limitations:
Currently the simulator only supports the Euler method, Runge-Kutta Integration is not supported.
The SD model transpiler for XMILE models only supports regular stocks, flows, biflows and converters. Non-negative stocks and discrete modeling elements (such as ovens and conveyors) are not supported.
Subranges for arrays are currently not supported.
The inner product operator for arrays is currently not supported.
Special notations for arrays (e.g. N1:N2 and @) are currently not supported.
The random number operators (LOGNORMAL, LOGISTIC etc.) support seed but uses the Python seed and random number generator as the Stella Architect random number function is not open source. Secondly, these operators only support the mandatory arguments (usually mean/scale/stddev) as given in in the Stella documentation
INTis transpiled to Python’smath.floor. The two agree for positive numbers and differ for negative ones, where Stella truncates towards zero andfloorrounds down:INT(-2.5)is -2 in Stella and -3 here.The following table gives an overview of all XMILE builtins, whether they are supported by the SD model transpiler for XMILE and their equivalent in the SD DSL library – blank cells indicate that the operator is currently not supported. We are working hard to ensure support for all operators is included ASAP. Built-ins pertaining to discrete elements are not listed.
Entries written
Element.arr_…are methods on an arrayed model element rather than functions insd_functions; see Element.
| Built-In | SD model transpiler | SD DSL equivalent |
|---|---|---|
| ABS | x | abs |
| AND | x | And |
| ARCCOS | x | arccos |
| ARCSIN | x | arcsin |
| ARCTAN | x | arctan |
| BETA | x | beta |
| BINOMIAL | x | binomial |
| COMBINATIONS | x | combinations |
| COS | x | cos |
| CGROWTH | x | - |
| CLOCKTIME | x | - |
| COSWAVE | x | coswave |
| COUNTER | x | - |
| DELAY | x | delay |
| DELAY1 | x | - |
| DELAY3 | x | - |
| DELAYN | x | - |
| DERIVN | x | - |
| DT | x | dt |
| ELSE | x | If |
| EXP | x | exp |
| EXPRND | x | exprnd |
| ENDVAL | x | - |
| FACTORIAL | x | factorial |
| FORCST | x | - |
| FV | x | - |
| GAMMA | x | gamma |
| GAMMALN | x | gammaln |
| GEOMETRIC | x | geometric |
| HISTORY | x | - |
| IF | x | If |
| INF | x | Inf |
| INTERPOLATE | x | - |
| INIT | x | - |
| INT | x | floor |
| INVNORM | x | invnorm |
| IRR | x | - |
| LOG10 | x | log10 |
| LOGISTIC | x | logistic |
| LOGNORMAL | x | lognormal |
| LOOKUP | x | lookup |
| LOOKUPAREA | x | - |
| LOOKUPINV | x | - |
| LN | x | ln |
| MAX | x | max |
| MEAN | x | Element.arr_mean |
| MIN | x | min |
| MOD | x | % (simply use the Python mod operator) |
| MONTECARLO | x | montecarlo |
| NAN | x | nan |
| NEGBINOMIAL | x | negbinomial |
| NORMAL | x | normal |
| NORMALCDF | x | normalcdf |
| NOT | x | Not |
| NPV | x | - |
| OR | x | Or |
| PARETO | x | pareto |
| PERCENT | x | - |
| PERMUTATIONS | x | permutations |
| PI | x | pi |
| PMT | x | - |
| POISSON | x | poisson |
| PREVIOUS | x | - |
| PULSE | x | pulse |
| PV | x | - |
| PROD | x | Element.arr_prod |
| RANDOM | x | random |
| RANK | x | Element.arr_rank |
| RAMP | x | - |
| REWORK | - | - |
| ROUND | x | round |
| ROOTN | x | - |
| RUNCOUNT | - | - |
| SAFEDIV | x | - |
| SELF | x | - |
| SENSIRUNCOUNT | - | - |
| SIN | x | sin |
| SINWAVE | x | sinwave |
| SIZE | x | Element.arr_size |
| SMTH1 | x | smooth |
| SMTH3 | x | - |
| SMTHN | x | - |
| SQRT | x | sqrt |
| STARTTIME | x | starttime |
| STDDEV | x | Element.arr_stddev |
| STEP | x | step |
| STOPTIME | x | stoptime |
| SUM | x | Element.arr_sum |
| TAN | x | tan |
| THEN | x | If |
| TIME | x | time |
| TREND | x | trend |
| TRIANGULAR | x | triangular |
| UNIFORM | x | uniform |
| WEIBULL | x | weibull |