XMILE in the SD DSL
system dynamics, xmile, smile, stella, sd dsl, bptk, bptk-py, python, builtins, transpiler
XMILE in the SD DSL
A model written in XMILE - in Stella, say - reaches BPTK-Py in one of two ways. The transpiler turns the file into a Python class, as XMILE Step by Step shows. Or you write the model again in the SD DSL, by hand. This chapter puts the two side by side: for every XMILE builtin, what the SD DSL calls it, which engine runs it and whether the transpiler compiles it.
- Builtins Side by Side: every builtin as an XMILE equation and the SD DSL call that computes the same
- Built from Other Functions:
SELF,CLOCKTIME,ENDVAL,RUNCOUNTandSENSIRUNCOUNT, which the SD DSL writes with what it has - Model Structure: stocks, flows, conveyors, graphical functions, arrays and run specs in XML and in Python
Every builtin at a glance
sd is BPTK_Py.sd_functions; element.arr_... is a method of an arrayed element. Every SD DSL function runs on the Python engine. A random function with a seed does not run on the Rust engine yet, whatever the table says about the function itself. Queues and ovens are not listed: neither the SD DSL nor the transpiler has them.
| XMILE | SD DSL | Rust engine | Transpiler |
|---|---|---|---|
| ABS | sd.abs |
x | x |
| AGECOUNT | sd.agecount |
- | - |
| AND | sd.And |
x | x |
| ARCCOS | sd.arccos |
x | x |
| ARCSIN | sd.arcsin |
x | x |
| ARCTAN | sd.arctan |
x | x |
| BETA | sd.beta |
x | x |
| BINOMIAL | sd.binomial |
x | x |
| COMBINATIONS | sd.combinations |
x | partly |
| COS | sd.cos |
x | x |
| CGROWTH | sd.cgrowth |
x | x |
| CLOCKTIME | a user-defined function | x | x |
| COSWAVE | sd.coswave |
x | x |
| COUNTER | sd.counter |
x | partly |
| DELAY | sd.delay |
x | x |
| DELAY1 | sd.delay1 |
x | x |
| DELAY3 | sd.delay3 |
x | x |
| DELAYN | sd.delayn |
x | x |
| DERIVN | sd.derivn |
x | partly |
| DT | sd.dt |
x | x |
| ELSE | sd.If |
x | x |
| EXP | sd.exp |
x | x |
| EXPRND | sd.exprnd |
x | x |
| ENDVAL | a second scenario | x | x |
| FACTORIAL | sd.factorial |
x | x |
| FORCST | sd.forecast |
x | partly |
| FV | sd.fv |
x | x |
| GAMMA | sd.gamma |
x | x |
| GAMMALN | sd.gammaln |
x | x |
| GEOMETRIC | sd.geometric |
x | x |
| HISTORY | sd.history |
x | x |
| IF | sd.If |
x | x |
| INF | sd.Inf |
x | x |
| INTERPOLATE | sd.interpolate |
- | x |
| INIT | sd.init |
x | x |
| INT | sd.floor |
x | x |
| INVNORM | sd.invnorm |
x | x |
| IRR | sd.irr |
- | partly |
| LOG10 | sd.log10 |
x | x |
| LOGISTIC | sd.logistic |
x | x |
| LOGNORMAL | sd.lognormal |
x | x |
| LOOKUP | sd.lookup |
x | x |
| LOOKUPAREA | sd.lookuparea |
- | x |
| LOOKUPINV | sd.lookupinv |
- | x |
| LN | sd.ln |
x | x |
| MAX | sd.max |
x | x |
| MEAN | element.arr_mean |
x | x |
| MIN | sd.min |
x | x |
| MOD | % |
x | x |
| MONTECARLO | sd.montecarlo |
x | x |
| NAN | sd.nan |
x | x |
| NEGBINOMIAL | sd.negbinomial |
x | x |
| NORMAL | sd.normal |
x | x |
| NORMALCDF | sd.normalcdf |
x | x |
| NOT | sd.Not |
x | x |
| NPV | sd.npv |
x | x |
| OR | sd.Or |
x | x |
| PARETO | sd.pareto |
x | x |
| PERCENT | sd.percent |
x | x |
| PERMUTATIONS | sd.permutations |
x | x |
| PI | sd.pi |
x | x |
| PMT | sd.pmt |
x | x |
| POISSON | sd.poisson |
x | x |
| PREVIOUS | sd.previous |
x | x |
| PULSE | sd.pulse |
x | partly |
| PV | sd.pv |
x | x |
| PROD | element.arr_prod |
x | x |
| RANDOM | sd.random |
x | x |
| RANK | sd.rank |
- | x |
| RAMP | sd.ramp |
x | x |
| REWORK | - | - | - |
| ROUND | sd.round |
x | x |
| ROOTN | sd.rootn |
x | x |
| RUNCOUNT | a constant set per run | x | - |
| SAFEDIV | sd.safediv |
x | x |
| SELF | sd.previous on the element itself |
x | x |
| SENSIRUNCOUNT | a constant set per run | x | - |
| SIN | sd.sin |
x | x |
| SINWAVE | sd.sinwave |
x | x |
| SIZE | element.arr_size |
x | x |
| SMTH1 | sd.smooth |
x | partly |
| SMTH3 | sd.smooth3 |
x | x |
| SMTHN | sd.smoothn |
x | x |
| SQRT | sd.sqrt |
x | x |
| STARTTIME | sd.starttime |
x | x |
| STDDEV | element.arr_stddev |
x | x |
| STEP | sd.step |
x | x |
| STOPTIME | sd.stoptime |
x | x |
| SUM | element.arr_sum |
x | x |
| TAN | sd.tan |
x | x |
| THEN | sd.If |
x | x |
| TIME | sd.time |
x | x |
| TREND | sd.trend |
x | partly |
| TRIANGULAR | sd.triangular |
x | x |
| UNIFORM | sd.uniform |
x | x |
| WEIBULL | sd.weibull |
x | x |
Where the transpiler differs
Eight builtins marked partly above compile, but not in every form. Each case is checked against the SD DSL with the rows of Builtins Side by Side:
SMTH1andTRENDfail to compile with a number as an argument, or without their optional third one;FORCSTfails to compile in every form.TRENDwith an initial trend reads it as the starting value of the internal average.COUNTERcounts fromTIMErather than fromSTARTTIME, so it is right only in a model that starts at the counter’s start value; with a start of 0 it fails to compile.DERIVNtakes only a variable, not an expression;COMBINATIONStakes no number with a decimal point;IRRfails to compile.PULSEwithout a first pulse time pulses at every DT rather than once at the start.
What the transpiler does not compile
- Discrete elements: ovens, queues and conveyors. The SD DSL has conveyors - see Conveyor - though not leak zones, capacity, inflow limits, arrest or discrete conveyors.
- Non-negative stocks only approximately: the stock is held at zero, but its outflows are not reduced, so they keep draining what the stock no longer has. The SD DSL has them as Stella does - see Stock.non_negative.
- Subranges of arrays and their notations (
N1:N2,@, the transpose operator'). The SD DSL has ranges and transposition - see Parts of an array - but not@: its arrays have labels, not named dimensions. - The optional arguments of the random functions: the transpiled functions take only the mandatory ones - usually mean, scale or standard deviation - as given in the Stella documentation. A
seedis taken, but it resets Python’s generator at the start of the run, so the seed of one function moves the others too; in the SD DSL each function with a seed draws a sequence of its own - see Seeds. Neither draws Stella’s numbers: Stella’s random number generator is not open source.