User-defined Functions and Arrayed Models
system dynamics, systemdynamics, sd dsl, arrays, user-defined functions, bptk, bptk-py, python, business simulation
User-defined Functions and Arrayed Models
A user-defined function can take an arrayed element as its argument, and a function says once - when it is registered - what that should mean.
By default a function is applied per index, which is the rule every operator in the DSL follows: the result is an array of the same shape, and a named array keeps its labels.
A function declared with elementwise=False receives the whole array instead and answers once. An unnamed array arrives as a list, a named one as a dict keyed by its labels, and a matrix arrives nested. The result is a single value, so anything built on top of it is scalar too.
250.0
Which of the two you want is a property of the function, not of the call, so it is stated where the function is registered. The default is the element-wise one, because that is what every other operator does with an array.
The aggregations the DSL already carries - arr_sum, arr_mean, arr_max and the rest - need no function at all, and they run on the Rust engine. Reach for elementwise=False when the reduction is one the DSL does not have.
A function registered with elementwise=False cannot run on the Rust engine: a callback from the engine answers with one number per node, and such a function is handed a whole array. A model that uses one runs on the Python engine; asked to run on Rust, it is refused with a RustBackendError naming the function. Limitations lists what else stays on the Python engine.