List handling

product function

product([X])

product({X})

Result is the product of all elements of the array [X] or the list {X}

**Input**: numeric array or list

**Result**: numeric

**Example**:

product([2,3,4]) --> 24

In: Contents >> Working with equations >> Functions >> Built-in functions

place_in function

place_in(I)

When making an array with the makearray function, place_in() returns the current position in the array. If makearray() functions are nested one inside another, the argument to the place_in() function will determine which position is returned. An argument of 1 refers to the innermost makearray().

**Input**: integer

**Result**: integer

**Examples**:

makearray(if place_in(1)==1 then 10 else 5, 4) --> [10, 5, 5, 5]

makearray(if place_in(1)==2 then 10 else 5, 4) --> [5, 10, 5, 5]

makearray(makearray(if place_in(2)==1 then 10 else 5, 4), 2) --> [[10, 10, 10, 10], [5, 5, 5, 5]]

makearray(makearray(if place_in(1)==1 then 10 else 5, 4), 2) --> [[10, 5, 5, 5], [10, 5, 5, 5]]

makearray(4*place_in(1),12) --> [4 8 12 16 20 24 28 32 36 40 44 48]

makearray(makearray(place_in(1)*place_in(2),12),12) -->

[[1 2 3 4 5 6 7 8 9 10 11 12],

[2 4 6 8 10 12 14 16 18 20 22 24],

[3 6 9 12 15 18 21 24 27 30 33 36],

[4 8 12 16 20 24 28 32 36 40 44 48],

[5 10 15 20 25 30 35 40 45 50 55 60],

[6 12 18 24 30 36 42 48 54 60 66 72],

[7 14 21 28 35 42 49 56 63 70 77 84],

[8 16 24 32 40 48 56 64 72 80 88 96],

[9 18 27 36 45 54 63 72 81 90 99 108],

[10 20 30 40 50 60 70 80 90 100 110 120,

[11 22 33 44 55 66 77 88 99 110 121 132],

[12 24 36 48 60 72 84 96 108 120 132 144]]

**Comments**:

This function is only meaningful inside makearray() function. If used elsewhere, the equation parser will signal an error.

In: Contents >> Working with equations >> Functions >> Built-in functions

makearray function

makearray(X,N)

Makes an array consisting of N lots of X

**Input**: any type, numeric

**Result**: array of same type

**Examples**:

makearray(7, 3) --> [7, 7, 7]

makearray([rand_var(0, 1), rand_var(0, 5)], 5) --> [[0.62352, 2.43459], [0.11933, 0.423529], [0.94208, 4.43623], [0.40088, 1.63023], [0.11769, 4.97782]]

**Comments**:

This is an array constructor. The first argument can be any expression, and the second is an integer. The result is an array, each of whose elements is generated by evaluating the first argument. The size of the array is the value of the second argument, which must be a constant. If the first argument is an array, the result will be an array of arrays. See also the place_in function, which is used in complex constructions with makearray.

Use of makearray() is called *explicit replication*. It differs from implicit replication in that the expression being replicated is evaluated separately for each member of the generated array, including any implicit (but not explicit) intermediate results. This means that no attempt is made to combine the dimensions of the two arguments. The second argument must be a scalar integer, and the result will be an array whose outermost dimension is that value, and whose inner dimensions are the dimensions of the first argument.

makearray() could have been designed to work differently on an array first argument, replicating each element rather than the whole array. As in the case of implicit replication, the actual behaviour was chosen to be that which would be hardest to achieve by combining other functions. If you need to replicate the elements of an array, you can first split it up with the element() function then rejoin the results with makearray, e.g., makearray(makearray(element([3,6,9],place_in(2)),2),3) -> [[3,3],[6,6],[9,9]], whereas if makearray itself worked like this, it would be very hard to get its actual behaviour.

See also: place_in function

In: Contents >> Working with equations >> Functions >> Built-in functions

**with_greatest([N], [X]) with_greatest({N}, {X})**

Returns the value from an array [X] or the list {X} whose position in the array or list corresponds to the largest value in the array [N] or list {N}.

Inputs: numeric array or list, same dimensioned array or list with members of any type

Result: single value from second input

Example:

with_greatest([2,5,7,3], ["red", "blue", "green", "yellow"]) --> "green"

This example would require the definition of an enumerated type with the members "red", "blue", "green" and "yellow".

In: Contents >> Working with equations >> Functions >> Built-in functions

sum function

sum([X])

sum({X})

Result is the sum of all elements of the array [X] or the list {X}

**Input**: numeric array/list

**Result**: numeric

**Example**:

sum([2,3,4]) --> 9

sum([[1,2],[3,4]]) --> [4,6]

**Comment**:

Note the behaviour with nested arrays. A new array results, consisting of the sum of the first value of each array, the sum of the second value of each array, etc.

sum function

sum([X])

sum({X})

Result is the sum of all elements of the array [X] or the list {X}

**Input**: numeric array/list

**Result**: numeric

**Example**:

sum([2,3,4]) --> 9

sum([[1,2],[3,4]]) --> [4,6]

**Comment**:

Note the behaviour with nested arrays. A new array results, consisting of the sum of the first value of each array, the sum of the second value of each array, etc. The reason it is implemented this way is that the converse (generating an array of the sums of each sub-array in the original, i.e., [3,7] in the above example) is easier to generate explicitly if required. In the case where the 2-D array is a value coming out of nested 1-D submodels, it can be produced by putting the sum() function inside the outer submodel. If the array is only available as a 2-D value, the same effect can be produced using the element() and makearray() functions as follows:

makearray(sum(element([[1,2],[3,4]], place_in(1))),2) --> [3,7]

All other cumulative functions behave the same way regarding selection of elements from multidimensional arrays.

In: Contents >> Working with equations >> Functions >> Built-in functions

Takes an array of numeric values and returns an array containing the indices of those values in ascending order.

Example:

order([1,9,2,10,3,8,5]) -> [1,3,5,7,6,2,4]

Note that the result of order() can be used to get the original values in ascending order by using it in the element function. e.g.,

mixed = [1,9,2,10,3,8,5]

sort = order(mixed)

element([mixed],[sort]) -> [1,2,3,5,8,9,10]

In: Contents >> Working with equations >> Functions >> Built-in functions

interpolate(X, [Xarray], [Yarray])

X is an input value. The arrays Xarray and Yarray define a series of coordinates. They must contain the same number of elements, and the values in Xarray must be in ascending order. If the value of X is less than the first element of Xarray, then the result is the first element of Yarray. If the value of X is greater than the last element of Xarray, then the result is the last element of Yarray. Otherwise, the result is the value obtained by linear interpolation between the two points which bracket the value of X.

Examples:

interpolate(3, [2,4,7], [10,20,30]) --> 15 (linear interpolation between the points (2,10) and (4,20))

interpolate(1, [2,4,7], [10,20,30]) --> 10 (X value is less than first element of Xarray, so use first element of Yarray)

interpolate(9, [2,4,7], [10,20,30]) --> 30 (X value is greater than first element of Xarray, so use last element of Yarray)

In: Contents >> Working with equations >> Functions >> Built-in functions

Takes an array of numeric values, and returns an array with the ranks of the corresponding elements in the argument. This is 1 for the largest element, and equal to the size of the array for the smallest.

Example:

rankings([1,9,2,10,3,8,5]) -> [7,2,6,1,5,3,4]

In: Contents >> Working with equations >> Functions >> Built-in functions

Takes an array of numeric values, and returns an array containing the running totals from summing the elements in the original array.

Example:

subtotals([1,9,2,10,3,8,5]) -> [1,10,12,22,25,33,38]

In: Contents >> Working with equations >> Functions >> Built-in functions

element function

element([X],I)

Picks the I^{th} value from the array [X]

**Inputs**: an array [X] of any type

integer I

**Result**: type

**Examples**:

element([10,20,30,40],3) --> 30 (since 30 is the value of the 3rd element of the array.

element([[1,2], [3,4], [5,6]],2) --> [3,4] (since the array [3,4] is the 2nd element of the input array)

element([10,20,30,40],index(1)) --> 10 for the first instance of a four-instance submodel, 20 for the second instance, etc, since index(1) has the value 1 for the first instance, 2 for the second instance, etc.

**Comments**:

This is an essential function for use with multiple-instance submodels, in which case it is almost always used in combination with the function index(1) in the second argument. One common use is to provide each instance of a multiple-instance submodel with a unique value for some parameter or other value. The third example (above) illustrates this: that could, for example, be the expression in a compartment element inside a four-instance submodel, initialising the compartment for each of the four instances to 10, 20, 30 and 40 respectively.

For advanced users:

The element function has rather more power than suggested above. The second argument can act as a sort of template to say how values (or sub-arrays) from the first argument are to be picked up. This is illustrated by the following example:

element([3,2,7,4,9,34,1,5], [[5,2], [1,5]]) --> [[9,2], [3,9]]

If the first argument is multidimensional and the second argument is a one-dimensional array, the elements of the second argument will be used to pick elements from the innermost arrays of the first argument from whuch to build the result, e.g.,

element([[3,5,11], [1,2,8]], [2,1,2]) --> [1,5,8].

The reason it works this way is that the converse behaviour, i.e., each element of the second argument selecting a value from the corresponding element of the first argument, is easy to get in the case where the first argument is a value from a nested submodel by putting the element() function inside the outer submodel, and can be obtained in general by building up from simple cases, e.g.,

makearray(element(element([[3,5,11], [1,2,8]],place_in(1)), element([3,1], place_in(1))), 2) --> [11,1].

makearray(element([[5,7],[1,4],[8,5]], element([3,3,2,2], place_in(1))), 4) --> [[8,5], [8,5], [1,4], [1,4]]

Starting with Simile version 6.1, it is possible to have a list-valued expression as the first argument of element(), in which case the result is a sublist of that list, i.e., a list containing some, all or none of the members of the original list in the same order. The second argument can be a single value, in which case the resulting list has one element if the list includes a value with that index, and none otherwise. So applying sum() to it gives either a value from the original list or zero.

If the second argument is an array or list, the result is a sublist of the first argument containing all the values whose indices appear as values in the second argument. There are a few points to note about all these uses:

- It is not computationally efficient. The values from the list are found by searching through it sequentially rather than by lookup as can be done on arrays.
- If the second argument is an array or list, its values must be in ascending order, or in the order in which they appear in the definition if they are of an enumerated type. If a value occurs more than once in the second argument, the value with that index will still only appear once in the result. This is because rather than searching the list from the start for each value, the generated code merely starts from where the last one was found, since the indices in the original list should always be in ascending order. (This does not apply when selecting a sublist from a list of neighbour values in a special-purpose submodel; the direction identifiers can be in any order, and if one occurs more than once, its value from the original list will also be repeated).
- The resulting list cannot itself be used as the first argument of element(), or arithmetically combined with other list-valued expressions.

**element() with multiple indices**

Starting with Simile version 6.1, if you have a 2-D (or higher) array, you can look up a single member by using element() with 3 (or more) arguments, e.g.,

element([[arr]], x, y)

Formerly you would have had to do this by nesting element() calls, but the new format is neater and allows the indices to be matching arrays or lists themselves to get multiple values.

Examples:

element([[6,1,8],[7,5,3],[2,9,4]], 2, 2) --> 5

element([[6,1,8],[7,5,3],[2,9,4]], [2,1,3], [3,1,2]) --> [3,6,9]

In: Contents >> Working with equations >> Functions >> Built-in functions

any function

any(([X])

any({X})

Result is true if any of the elements of the array [X] or the list {X} are true.

**Input: ** boolean array or list

**Result: ** boolean

Examples:

any([false,false,false,true,false]) --> true

any([false,false,false]) --> false

In: Contents >> Working with equations >> Functions >> Built-in functions

all function

all([X])

all({X})

Result is true if all the elements of the array [X] or the list {X} are true

**Input**: boolean array/list

**Result**: boolean

**Examples**:

all([true,true,true,false]) --> false

all([true,true,true,true]) --> true

In: Contents >> Working with equations >> Functions >> Built-in functions

least([X])

least({X})

Returns the smallest value from an array [X] or the list {X}

Inputs: numeric array/list

Result: numeric

Example:

least([2,5,7,3]) --> 2

In: Contents >> Working with equations >> Functions >> Built-in functions

greatest function

greatest([X])

greatest({X})

Returns the largest value from an array [X] or the list {X}

**Inputs**: numeric array or list

**Result**: numeric

**Example**:

greatest([2,5,7,3]) --> 7

In: Contents >> Working with equations >> Functions >> Built-in functions

**with_least([N], [X]) with_least({N}, {X})**

Returns the value from an array [X] or the list {X} whose position in the array or list corresponds to the smallest value in the array [N] or list {N}.

Inputs: numeric array or list, same dimensioned array or list with members of any type

Result: single value from second input

Example:

with_least([2,5,7,3], ["red", "blue", "green", "yellow"]) --> "red"

This example would require the definition of an enumerated type with the members "red", "blue", "green" and "yellow".

In: Contents >> Working with equations >> Functions >> Built-in functions