Python functions and stateful objects

Functions

The provided functions have no direct analog in the standard Python data analytics stack, or require information about the internal state of the system beyond what is present in the function call. They are provided in a structure that makes it easy for the model elements to call. The functions may be similar to the original functions given by Vensim or Stella, but sometimes the number or order of arguments may change.

pysd.py_backend.functions.ramp(time, slope, start, finish=None)[source]

Implements vensim’s and xmile’s RAMP function.

Parameters:
  • time (pysd.py_backend.components.Time) – Model time object.

  • slope (float or xarray.DataArray) – The slope of the ramp starting at zero at time start.

  • start (float or xarray.DataArray) – Time at which the ramp begins.

  • finish (float or xarray.DataArray or None (oprional)) – Time at which the ramp ends. If None the ramp will never end. Default is None.

Returns:

If prior to ramp start, returns zero. If after ramp ends, returns top of ramp.

Return type:

float or xarray.DataArray

pysd.py_backend.functions.step(time, value, tstep)[source]

” Implements vensim’s STEP function.

Parameters:
  • time (pysd.py_backend.components.Time) – Model time object.

  • value (float or xarray.DataArray) – The height of the step.

  • tstep (float or xarray.DataArray) – The time at and after which result equals value.

Returns:

  • In range [-inf, tstep):

    returns 0

  • In range [tstep, +inf]:

    returns value

Return type:

float or xarray.DataArray

pysd.py_backend.functions.pulse(time, start, repeat_time=0, width=None, magnitude=None, end=None)[source]

Implements Vensim’s PULSE and PULSE TRAIN functions and Xmile’s PULSE function.

Parameters:
  • time (pysd.py_backend.components.Time) – Model time object.

  • start (float) – Starting time of the pulse.

  • repeat_time (float (optional)) – Time interval of the pulse repetition. If 0 it will return a single pulse. Default is 0.

  • width (float or None (optional)) – Duration of the pulse. If None only one-time_step pulse will be generated. Default is None.

  • magnitude (float or None (optional)) – The magnitude of the pulse. If None it will return 1 when the pulse happens, similar to magnitude=time_step(). Default is None.

  • end (float or None (optional)) – Final time of the pulse. If None there is no final time. Default is None.

Returns:

  • In range [-inf, start):

    returns 0

  • In range [start + n*repeat_time, start + n*repeat_time + width):

    returns magnitude/time_step or 1

  • In range [start + n*repeat_time + width, start + (n+1)*repeat_time):

    returns 0

Return type:

float or xarray.DataArray

pysd.py_backend.functions.if_then_else(condition, val_if_true, val_if_false)[source]

Implements Vensim’s IF THEN ELSE function. https://www.vensim.com/documentation/20475.htm

Parameters:
  • condition (bool or xarray.DataArray of bools) –

  • val_if_true (callable) – Value to evaluate and return when condition is true.

  • val_if_false (callable) – Value to evaluate and return when condition is false.

Returns:

The value depending on the condition.

Return type:

float or xarray.DataArray

pysd.py_backend.functions.xidz(numerator, denominator, x)[source]

Implements Vensim’s XIDZ function. https://www.vensim.com/documentation/fn_xidz.htm

This function executes a division, robust to denominator being zero. In the case of zero denominator, the final argument is returned.

Parameters:
Returns:

  • numerator/denominator if denominator > small_vensim

  • value_if_denom_is_zero otherwise

Return type:

float or xarray.DataArray

pysd.py_backend.functions.zidz(numerator, denominator)[source]

This function bypasses divide-by-zero errors, implementing Vensim’s ZIDZ function. https://www.vensim.com/documentation/fn_zidz.htm

Parameters:
Returns:

  • numerator/denominator if denominator > small_vensim

  • 0 or 0s array otherwise

Return type:

float or xarray.DataArray

pysd.py_backend.functions.active_initial(stage, expr, init_val)[source]

Implements vensim’s ACTIVE INITIAL function

Parameters:
  • stage (str) – The stage of the model.

  • expr (callable) – Running stage value

  • init_val (float or xarray.DataArray) – Initialization stage value.

Returns:

  • inti_val if stage=’Initialization’

  • expr() otherwise

Return type:

float or xarray.DataArray

pysd.py_backend.functions.incomplete(*args)[source]

Implements an incomplete functions. Prompts a RuntimeWarning.

Parameters:

*args (arguments) –

Return type:

numpy.nan

pysd.py_backend.functions.not_implemented_function(*args)[source]

Implements a not implemented functions. Raises a NotImplementedError if it is called.

Parameters:

*args (arguments) – The first argument must be the name of the function as str to properly print the error message.

pysd.py_backend.functions.integer(x)[source]

Implements Vensim’s INTEGER function.

Parameters:

x (float or xarray.DataArray) – Input value.

Returns:

integer – Returns integer part of x.

Return type:

float or xarray.DataArray

pysd.py_backend.functions.quantum(a, b)[source]

Implements Vensim’s QUANTUM function.

Parameters:
Returns:

quantum – If b > 0 returns b * integer(a/b). Otherwise, returns a.

Return type:

float or xarray.DataArray

pysd.py_backend.functions.modulo(x, m)[source]

Implements Vensim’s MODULO function.

Parameters:
Returns:

modulo – Returns x modulo m, if x is smaller than 0 the result is given in the range (-m, 0] as Vensim does. x - quantum(x, m)

Return type:

float or xarray.DataArray

pysd.py_backend.functions.sum(x, dim=None)[source]

Implements Vensim’s SUM function.

Parameters:
  • x (xarray.DataArray) – Input value.

  • dim (list of strs (optional)) – Dimensions to apply the function over. If not given the function will be applied over all dimensions.

Returns:

sum – The result of the sum operation in the given dimensions.

Return type:

xarray.DataArray or float

pysd.py_backend.functions.prod(x, dim=None)[source]

Implements Vensim’s PROD function.

Parameters:
  • x (xarray.DataArray) – Input value.

  • dim (list of strs (optional)) – Dimensions to apply the function over. If not given the function will be applied over all dimensions.

Returns:

prod – The result of the product operation in the given dimensions.

Return type:

xarray.DataArray or float

pysd.py_backend.functions.vmin(x, dim=None)[source]

Implements Vensim’s Vmin function.

Parameters:
  • x (xarray.DataArray) – Input value.

  • dim (list of strs (optional)) – Dimensions to apply the function over. If not given the function will be applied over all dimensions.

Returns:

vmin – The result of the minimum value over the given dimensions.

Return type:

xarray.DataArray or float

pysd.py_backend.functions.vmax(x, dim=None)[source]

Implements Vensim’s VMAX function.

Parameters:
  • x (xarray.DataArray) – Input value.

  • dim (list of strs (optional)) – Dimensions to apply the function over. If not given the function will be applied over all dimensions.

Returns:

vmax – The result of the maximum value over the dimensions.

Return type:

xarray.DataArray or float

pysd.py_backend.functions.invert_matrix(mat)[source]

Implements Vensim’s INVERT MATRIX function.

Invert the matrix defined by the last two dimensions of xarray.DataArray.

Parameters:

mat (xarray.DataArray) – The matrix to invert.

Returns:

mat1 – Inverted matrix.

Return type:

xarray.DataArray

pysd.py_backend.functions.vector_select(selection_array, expression_array, dim, missing_vals, numerical_action, error_action)[source]

Implements Vensim’s VECTOR SELECT function. http://vensim.com/documentation/fn_vector_select.html

Parameters:
  • selection_array (xr.DataArray) – This specifies a selection array with a mixture of zeroes and non-zero values.

  • expression_array (xarray.DataArray) – This is the expression that elements are being selected from based on the selection array.

  • dim (list of strs) – Dimensions to apply the function over.

  • missing_vals (float) – The value to use in the case where there are only zeroes in the selection array.

  • numerical_action (int) –

    The action to take:
    • 0 It will calculate the weighted sum.

    • 1 When values in the selection array are non-zero, this will calculate the product of the selection_array * expression_array.

    • 2 The weighted minimum, for non zero values of the selection array, this is minimum of selection_array * expression_array.

    • 3 The weighted maximum, for non zero values of the selection array, this is maximum of selection_array * expression_array.

    • 4 For non zero values of the selection array, this is the average of selection_array * expression_array.

    • 5 When values in the selection array are non-zero, this will calculate the product of the expression_array ^ selection_array.

    • 6 When values in the selection array are non-zero, this will calculate the sum of the expression_array. The same as the SUM function for non-zero values in the selection array.

    • 7 When values in the selection array are non-zero, this will calculate the product of the expression_array. The same as the PROD function for non-zero values in the selection array.

    • 8 The unweighted minimum, for non zero values of the selection array, this is minimum of the expression_array. The same as the VMIN function for non-zero values in the selection array.

    • 9 The unweighted maximum, for non zero values of the selection array, this is maximum of expression_array. The same as the VMAX function for non-zero values in the selection array.

    • 10 For non zero values of the selection array, this is the average of expression_array.

  • error_action (int) –

    Indicates how to treat too many or too few entries in the selection:
    • 0 No error is raised.

    • 1 Raise a floating point error is selection array only contains zeros.

    • 2 Raise an error if the selection array contains more than one non-zero value.

    • 3 Raise an error if all elements in selection array are zero, or more than one element is non-zero (this is a combination of error_action = 1 and error_action = 2).

Returns:

result – The output of the numerical action.

Return type:

xarray.DataArray or float

pysd.py_backend.functions.vector_sort_order(vector, direction)[source]

Implements Vensim’s VECTOR SORT ORDER function. Sorting is done on the complete vector relative to the last subscript. https://www.vensim.com/documentation/fn_vector_sort_order.html

Parameters:
  • vector (xarray.DataArray) – The vector to sort.

  • direction (float) – The direction to sort the vector. If direction > 0 it will sort the vector entries from smallest to biggest, otherwise from biggest to smallest.

Returns:

vector_sorted – The sorted vector.

Return type:

xarray.DataArray

pysd.py_backend.functions.vector_reorder(vector, svector)[source]

Implements Vensim’s VECTOR REORDER function. Reordering is done on the complete vector relative to the last subscript. https://www.vensim.com/documentation/fn_vector_reorder.html

Parameters:
Returns:

vector_sorted – The sorted vector.

Return type:

xarray.DataArray

pysd.py_backend.functions.vector_rank(vector, direction)[source]

Implements Vensim’s VECTOR RANK function. Ranking is done on the complete vector relative to the last subscript. https://www.vensim.com/documentation/fn_vector_rank.html

Parameters:
  • vector (xarray.DataArray) – The vector to sort.

  • direction (float) – The direction to sort the vector. If direction > 1 it will rank the vector entries from smallest to biggest, otherwise from biggest to smallest.

Returns:

vector_rank – The rank of the vector.

Return type:

xarray.DataArray

pysd.py_backend.functions.get_time_value(time, relativeto, offset, measure)[source]

Implements Vensim’s GET TIME VALUE function. Warning, not all the cases are implemented. https://www.vensim.com/documentation/fn_get_time_value.html

Parameters:
  • time (pysd.py_backend.components.Time) – Model time object.

  • relativeto (int) –

    The time to take as a reference:
    • 0 for the current simulation time.

    • 1 for the initial simulation time.

    • 2 for the current computer clock time.

  • offset (float or xarray.DataArray) – The difference in time, as measured in the units of Time for the model, to move before computing the value. offset is ignored when relativeto is 2.

  • measure (int) –

    The units or measure of time:
    • 0 units of Time in the model (only for relativeto 0 and 1)

    • 1 years since 1 BC (an integer, same as the normal calendar year)

    • 2 quarter of year (1-4)

    • 3 month of year (1-12)

    • 4 day of month (1-31)

    • 5 day of week (0-6 where 0 is Sunday)

    • 6 days since Jan 1., 1 BC (year 1 BC is treated as year 0)

    • 7 hour of day (0-23)

    • 8 minute of hour (0-59)

    • 9 second of minute (0-59.999999 – not an integer)

    • 10 elapsed seconds modulo 500,000 (0-499,999)

Returns:

time_value – The resulting time value.

Return type:

float or int

Allocation functions

The provided allocation functions have no direct analog in the standard Python data analytics stack. They are provided in a structure that makes it easy for the model elements to call. The functions may be similar to the original functions given by Vensim, but sometimes the number or order of arguments may change. The allocation functions may call a protected function or class method thatintegrates the algorithm to compute the allocation. The algorithms are briefly explained in these functions docstring.

Note

The Allocation functions basis is explained in the Vensim documentation. https://www.vensim.com/documentation/allocation_overview.html

Warning

Some allocation function’s results may differ from the result given by Vensim as optimization functions are used to solve the allocation problems. Those algorithms may not work in the same way or may have differences in the numerical error propagation.

pysd.py_backend.allocation.allocate_available(request, pp, avail)[source]

Implements Vensim’s ALLOCATE AVAILABLE function. https://www.vensim.com/documentation/fn_allocate_available.html

Parameters:
  • request (xarray.DataArray) – Request of each target. Its shape should be the one of the expected output of the function, having the allocation dimension in the last position.

  • pp (xarray.DataArray) – Priority of each target. Its shape should be the same as request with an extra dimension for the priority profiles in the last position. See Vensim’s documentation for more information https://www.vensim.com/documentation/24335.html

  • avail (float or xarray.DataArray) – The total supply available to fulfill all requests. If the supply exceeds total requests, all requests are filled, but none are overfilled. If you wish to conserve material you must compute supply minus total allocations explicitly. Its shape, should be the same of request without the last dimension.

Returns:

out – The distribution of the supply.

Return type:

xarray.DataArray

Warning

This function uses an optimization method for resolution and the given solution could differ from the one from Vensim. Particularly, when close to the boundaries of the defined priority profiles.

pysd.py_backend.allocation.allocate_by_priority(request, priority, width, supply)[source]

Implements Vensim’s ALLOCATE BY PRIORITY function. https://www.vensim.com/documentation/fn_allocate_by_priority.html

Parameters:
  • request (xarray.DataArray) – Request of each target. Its shape should be the same as priority. width and supply must have the same shape except the last dimension.

  • priority (xarray.DataArray) – Priority of each target. Its shape should be the same as request. width and supply must have the same shape except the last dimension.

  • width (float or xarray.DataArray) – Specifies how big a gap in priority is required to have the allocation go first to higher priority with only leftovers going to lower priority. When the distance between any two priorities exceeds width and the higher priority does not receive its full request the lower priority will receive nothing. Its shape should be the same as supply.

  • supply (float or xarray.DataArray) – The total supply available to fulfill all requests. If the supply exceeds total requests, all requests are filled, but none are overfilled. If you wish to conserve material you must compute supply minus total allocations explicitly. Its shape should be the same as width.

Returns:

out – The distribution of the supply.

Return type:

xarray.DataArray

Statefuls

The Stateful objects are used and updated each time step with an update method. This include Integs, Delays, Forecasts, Smooths, and Trends, between others. The Macro class and Model class are also Stateful type. However, they are defined appart as they are more complex.

class pysd.py_backend.statefuls.Integ(ddt, initial_value, py_name)[source]

Implements INTEG function.

Parameters:
  • ddt (callable) – Derivate to integrate.

  • initial_value (callable) – Initial value.

  • py_name (str) – Python name to identify the object.

state

Current state of the object. Value of the stock.

Type:

float or xarray.DataArray

class pysd.py_backend.statefuls.NonNegativeInteg(ddt, initial_value, py_name)[source]

Implements non negative INTEG function.

Parameters:
  • ddt (callable) – Derivate to integrate.

  • initial_value (callable) – Initial value.

  • py_name (str) – Python name to identify the object.

state

Current state of the object. Value of the stock.

Type:

float or xarray.DataArray

class pysd.py_backend.statefuls.Delay(delay_input, delay_time, initial_value, order, tstep, py_name)[source]

Implements DELAY function.

Parameters:
  • delay_input (callable) – Input of the delay.

  • delay_time (callable) – Delay time.

  • initial_value (callable) – Initial value.

  • order (callable) – Delay order.

  • tsetp (callable) – The time step of the model.

  • py_name (str) – Python name to identify the object.

state

Current state of the object. Array of the delays values multiplied by their corresponding average time.

Type:

numpy.array or xarray.DataArray

class pysd.py_backend.statefuls.DelayN(delay_input, delay_time, initial_value, order, tstep, py_name)[source]

Implements DELAY N function.

Parameters:
  • delay_input (callable) – Input of the delay.

  • delay_time (callable) – Delay time.

  • initial_value (callable) – Initial value.

  • order (callable) – Delay order.

  • tsetp (callable) – The time step of the model.

  • py_name (str) – Python name to identify the object.

state

Current state of the object. Array of the delays values multiplied by their corresponding average time.

Type:

numpy.array or xarray.DataArray

times

Array of delay times used for computing the delay output. If delay_time is constant, this array will be constant and DelayN will behave ad Delay.

Type:

numpy.array or xarray.DataArray

class pysd.py_backend.statefuls.DelayFixed(delay_input, delay_time, initial_value, tstep, py_name)[source]

Implements DELAY FIXED function.

Parameters:
  • delay_input (callable) – Input of the delay.

  • delay_time (callable) – Delay time.

  • initial_value (callable) – Initial value.

  • tsetp (callable) – The time step of the model.

  • py_name (str) – Python name to identify the object.

state

Current state of the object, equal to pipe[pointer].

Type:

float or xarray.DataArray

pipe

List of the delays values.

Type:

list

pointer

Pointer to the last value in the pipe

Type:

int

class pysd.py_backend.statefuls.Forecast(forecast_input, average_time, horizon, initial_trend, py_name)[source]

Implements FORECAST function.

Parameters:
  • forecast_input (callable) – Input of the forecast.

  • average_time (callable) – Average time.

  • horizon (callable) – Forecast horizon.

  • initial_trend (callable) – Initial trend of the forecast.

  • py_name (str) – Python name to identify the object.

state

Current state of the object. AV value by Vensim docs.

Type:

float or xarray.DataArray

class pysd.py_backend.statefuls.Smooth(smooth_input, smooth_time, initial_value, order, py_name)[source]

Implements SMOOTH function.

Parameters:
  • smooth_input (callable) – Input of the smooth.

  • smooth_time (callable) – Smooth time.

  • initial_value (callable) – Initial value.

  • order (callable) – Delay order.

  • py_name (str) – Python name to identify the object.

state

Current state of the object. Array of the inputs having the value to return in the last position.

Type:

numpy.array or xarray.DataArray

class pysd.py_backend.statefuls.Trend(trend_input, average_time, initial_trend, py_name)[source]

Implements TREND function.

Parameters:
  • trend_input (callable) – Input of the trend.

  • average_time (callable) – Average time.

  • initial_trend (callable) – Initial trend.

  • py_name (str) – Python name to identify the object.

state

Current state of the object. AV value by Vensim docs.

Type:

float or xarray.DataArray

class pysd.py_backend.statefuls.SampleIfTrue(condition, actual_value, initial_value, py_name)[source]

Implements SAMPLE IF TRUE function.

Parameters:
  • condition (callable) – Condition for sample.

  • actual_value (callable) – Value to update if condition is true.

  • initial_value (callable) – Initial value.

  • py_name (str) – Python name to identify the object.

state

Current state of the object. Last actual_value when condition was true or the initial_value if condition has never been true.

Type:

float or xarray.DataArray

class pysd.py_backend.statefuls.Initial(initial_value, py_name)[source]

Implements INITIAL function.

Parameters:
  • initial_value (callable) – Initial value.

  • py_name (str) – Python name to identify the object.

state

Current state of the object, which will always be the initial_value.

Type:

float or xarray.DataArray