Array builtins

Array builtins are designed to supplement the array capabilities of the software. Use these builtins to find the sum, the standard deviation, or the mean across dimensions of arrayed variables. Many of these functions work on array ranges, and there is in-depth discussion of this in Specialized Array Manipulation.

Some of these builtins can also be used for non-arrayed variables.

The array builtins can be applied to either an arrayed variable or an expression. Some can also be applied to conveyors and queues to deal with the elements within the stock.

Note Not all of the builtin functions can be used in Array expressions. You can't use any builtin that has a value depending on previous results (this includes the Delay builtins and Statistical builtins). You also can't use any other array builtins in the expression (it is not possible to nest array builtins.)

When an array builtin is applied to an expression, care must be taken to ensure that the intended dimensions are being reduced as expected.

 

This section describes the following builtins:

ALLOCATE(<available>, <index>, <target_array>, <priority_array>, <priority_spread>, [<shape>])

The ALLOCATE builtin determines a vector of quantities that can be used to distribute available across the different values of index. This is done based on a target for all indices specified in target_array with priorities (or attractiveness) specified in priority_array. It available is sufficient to satisfy the sum across target_array then the target value at index is returned. If available is not sufficient, a portion of it is provided based on the associated element in priority_array relative to the other elements. The argument priority_spread is used to determine whether portions of lower priority requests are supplied before all of higher priority requests are supplied. The optional shape argument determines the extent of that spreading.

If priority_spread is 0 then higher priority indices are supplied first. When it is positive higher priority indices will get a larger share or their target, but lower priority indices may also receive a portion of their target. shape determines the nature of this spread. The default 1 uses a rectangular spread, 2 a triangular spread (less sharing), 3 a normally distributed spread (more sharing), and 3 an exponentially distributed spread (even more sharing). It is useful to experiment with priority_spread and shape to get the desired allocation outcomes.

Both target_array and priority_array must be array slices of the same size across the values index takes on. available, priority_spread and shape can be any expression, but can not vary by index.

Examples:

ALLOCATE(candy_available,kid,appetite[*],weight[*],0) would share the candy among the kids with the heaviest kids getting the candy first, then the lighter kids. Both appetite and weight are arrayed by kid.

ALLOCATE(demand[product], producer, capacity[product,*], attractiveness[product,*], 2) would allocate product demand (by product) to different producers based on their capacity and attractiveness for that product. The 2 argument means that producers having attractiveness for the product within 2 of other producers will potentially sharing in that allocation.

ALLOCATE(funding,state,need[*],poverty_index[*],10,3) would allocate funding to different states based on their need (which would likely be proportional to population) with higher priority given to states with a higher poverty_index. Using a shape of 3 and a big spread means that people from all states would get something.

Note It is important that available, priority_spread and shape be the same for all values of index. Otherwise too much may be allocated or not all of the available amount used and some targets left unsatisfied.

Note The units of the first and third arguments should match, and will be the units returned. The units of the

INTERPOLATE(<arrayed variable>, <val1> [<val2>,...])

The INTERPOLATE builtin calculates the interpolated value of an N-dimensional set of points based on inputs computed on the unit interval [0,1]. It can be used to provide a continuous lookup mechanism for values that pass through all of the specified points. In 1 dimension this is the same as the behavior of a graphical function based on a vector of values.

The first argument must be an arrayed variable or a subset (slice) of an arrayed variable. For example, if there is a three dimensional array called points, then you could specify points directly with 3 additional arguments, or points[2,*,*] with 2 additional arguments.

The arguments should be normalized so they provide a value between 0 and 1. If the value is less than 0, the first entry in the associated dimension will be used. If the value is above 1, the last entry will be used. Between values the weighted average of the entry before the one associated with the input and the one after will be used. For example, if there are 5 entries, then a value of 0.3 would be between the second entry (at 0.25) and the third entry (at 0.5) and 80% of the value of the second entry and 20% of the value of the third would be used.

There must be at least 2 elements in each dimension of the arrayed variable, but there is no limited to how many there are beyond that, and no requirement that the different dimensions have the same number of entries. In all cases, the entries will be divided into an equal number of regions (n-1 internal and 2 external) and the results based on that.

Examples:

If pts[Dim1] is 0,2,4, then INTERPOLATE(pts, 0.75) would return 3.

If pts2d[Dim1,Dim2] is (0,2,4),(8,6,5) then INTERPOLATE(pts2d, 0.75, 0.25) would return 5.5. You can think of this as taking 25% of (0,2,4) and 75% of (8,6,5) to get (6,5, 4) and then taking the halfway point between 6 and 5 to get 5.5. Alternatively, since the 0.25 position of 3 numbers is half way between the first two, it works to take the halfway points between 0 and 1 (1) and that between 8 and 6 (7) then take 25% of 1 and 75% of 7 to get 22/4 or 5.5.

MEAN(<array or expression>)

The MEAN builtin calculates the arithmetic mean across the elements in the array or expression. The calculation is defined as the sum of the elements, divided by the number of elements in the array.

The MEAN calculation can be done in either an arrayed or a non-arrayed converter or flow.

To report the mean across a subset of the dimensions of the arrayed input variable, specify an asterisk (*) to include all of the elements across a dimension. You can report the arrayed variable's mean in either an arrayed or a non-arrayed converter or flow.

Examples:

Average Salary for Employees = MEAN(Salaries)

Average Salary for Employees in Boston = MEAN(Salaries[Boston,*])

Average Salary for Labor Groups 1 to 3 = MEAN(Salaries[*,1:3])

PERCENTILE(<arrayed variable>, <cut>[,<lower_cut>])

The PERCENTILE builtin calculates the value across an array slice that is reached the percent of the time specified by cut. For example if cut is 25 then 25% of all elements of the array slice will be below the value returned (and 75% above). If tlower_cutt is specificed then the value returned is the same as

PERCENTILE(array_slice,cut)-PERCENTILE(array_slice,lower_cut)

This is done to make it simply to use the output of PERCENTILE with an Area Graph where the different series build up from the min (0 cut) to the max (100 cut). If both cut and lower_cut are 0 then the minimum will be returned, otherwise cut must be greater than lower_cut or 0 will be returned.

Examples:

Median Salary for Employees = PERCENTILE(Salaries,50)

Maximum Salary for Employees in Boston = PERCENTILE(Salaries[Boston,*],100)

Minimum Salary for Labor Groups 1 to 3 = PERCENTILE(Salaries[*,1:3],0)

Difference between min and median for employees in Boston = PERCENTILE(Salaries[Boston,*],50,0)

PROD(<array or expression>)

The PROD builtin calculates the product of all the elements in the array or expression.

To report product across a subset of the dimensions of an arrayed input variable, specify an asterisk (*) to include all of the elements across a dimension, or a range specified (min:max) to report part of the array. You can use the arrayed variable's product in either an arrayed or a non-arrayed variable.

Example:

Interest_Factor[Year] = (1.0 + Interest_Rate[Year])

Compounded_Interest_to_Year[Year] = principal * PROD(Interest_Factor[1:year])

RANK(<arrayed variable>, <rank number>, [<secondary sort array>])

The RANK builtin gives the numerical index of the arrayed variable with the given rank number when the array is sorted in ascending order. The optional secondary sort array specifies the secondary sort field for variables with the same value. The secondary sort array must be the same size as the arrayed variable, or the secondary sort won't occur (this is only enforced when you simulate the model, so you won't be warned).

Example:

If array A contains the values { 6, 2, 8, 5 }

RANK(A, 2) will equal 4 (i.e., the fourth element of array A is the second smallest value)

Using RANK causes the specified array to be sorted once each time step (DT). For multi-dimensional arrays, you can pass one or more dimensions of the array to return the rank of a subset of the array.

Example:

Rank(Salaries[Boston,*],2) returns the rank of the second smallest salary in Boston.

SELF

Use the SELF builtin in conjunction with the SIZE, PREVIOUS, and ENDVAL builtins to refer to the current variable.

You can also use SELF[Dim1-1,Dim2] and similar forms to refer to different elements in an array. For example a variable arrayed by position could have the equation

IF position = 1 THEN 0 ELSE SELF[position-1] + width[position-1]

which would add the width of each successive position to compute the next position.

SIZE(<array or dimension>)

The SIZE builtin gives the number of elements in the array or dimension.

Note: You can also use the SIZE builtin to report the length of a queue.

To get information on the array holding the equation, use the SELF builtin.

Examples:

SIZE(Location) gives the number of elements in the dimension Location.

SIZE(sales) where sales is arrayed by location gives the number of elements in the dimension Location.

SIZE(SELF) gives the number of elements in this array.

SIZE(SELF[*, 1]) gives the size of the first dimension of this array.

SIZE(SELF[1, *]) gives the size of the second dimension of this array.

SIZE (<queue>) returns the total number of elements contained in the specified queue-type discrete stock.

SIZE (<conveyor>) returns the total number of slots contained in the specified conveyor-type discrete stock.

STDDEV(<array or expression>)

The STDDEV builtin calculates standard deviation for all the elements in the array or expression.

To report the standard deviation across a subset of the dimensions of an arrayed input variable, specify an asterisk (*) to include all of the elements across a dimension. You can report the arrayed variable's standard deviation in either an arrayed or a non-arrayed converter or flow.

Example:

Standard Deviation of Salary in Boston= STDDEV(Salaries[Boston,*])

SUM(<array or expression>)

The SUM builtin calculates the sum of all the elements in the array or expression.

To report the sum across a subset of the dimensions of an arrayed input variable, specify an asterisk (*) to include all of the elements across a dimension. You can report the arrayed variable's sum in either an arrayed or a non-arrayed converter or flow.

Example:

Total Salary for Employees in Boston = SUM(Salaries[Boston,*])

Concept Link IconSee Also