Modeling with Arrays

Forio arrays can help organize detailed model information by using the same equations to represent segments of the same item. For example, a sales model might have variables such as "Sales", "Price" and "Revenue" split among three different products.

Without arrays, nine variables would be required:

 

D Price1 = 100
D Price2 = 150
D Price3 = 175

V Sales1 = 100
V Sales2 = 200
V Sales3 = 150

V Revenue1 = Sales1 * Price1
V Revenue2 = Sales2 * Price2
V Revenue3 = Sales3 * Price3
 

 

However, the model can be considerably simplified with arrays:

 

R Products = books, cds, games

D Price[Products] = {100,150,175}

V Sales[Products] = {100, 200, 150}

V Revenue[Products] = Sales * Price
 

 

Not only are there less equations in the arrayed model, it is actually easier to understand. A model can reference a particular value by giving the name of the product, e.g. Price[books].

This document describes the syntax for using arrays in a Forio model.

Defining an Arrayed Element

To define an array element the modeler needs to specify a Dimension, indicating how the element is segmented, and an Equation.

For example, this defines a 5 segment array. The first and second are over a range of 1 to 5. The third is over a range of 11 to 15.

 

V MySales[1..5] = {100,200,300,400,500}

V MySales[5] = {100,200,300,400,500}

V MySales[11..15] = {100,200,300,400,500}
 

 

Arrays may also be multi-dimensional:

 

V MySales[5,2] = {{100,200}, {100,200}, {100,200}, {100,200}, {100,200}}
 

 

 

And finally, array definitions may contain literal values (as above) or equations. For example, the following is perfectly legal, defining three different equations for the three elements.

 

V MySales[3] = {New Sales + Repeat Sales, New Sales, New Sales}
 

 

To simplify the process of defining long arrays, a default value may be specified. The first example below creates an array with 100 and 200 for the first two values, and 1000 for all other values. The second example creates an array with the 5th element 1000 and the 2nd element 2000. The third example creates an array with the first five elements set to 1000.

 

V MySales[10] = {100, 200, Default: 1000}

V MySales[10] = {5: 1000, 2: 2000, Default: 6000}

V MySales2[10] = {1..5: 1000, Default: 6000}
 

 

Using the FOREACH Function to Define Arrays

One final way to define an array is to use the FOREACH function. This special function constructs an array over a particular range. The syntax is:

FOREACH(<item>, <range>, <expression>)

and can be read "for each item in the range, apply the expression".

 

For example, the following statements produce these results:

Equation

Result

FOREACH(item, 1..3, item * 2)

{2, 4, 6}

FOREACH(itemA, 1..2, FOREACH(itemB, 1..3, itemA * itemB))

{{1, 2, 3}, {2, 4, 6}}

 

FOREACH can also be used to sum across some of the dimensions of an array, or to combine arrays of different dimensions.

Using Arrayed Elements in Equations

Any array element can be combined with another array element of the same dimensions in an equation. This example adds each item in the two item array A and the two item array B, producing a new two item array C.

 

V A[2] = {100, 200}

V B[2] = {1000,2000}

V C[2] = A + B
 

 

Equations can also refer to individual elements in an array. The following scalar (non-arrayed) variable D is set to the first segment of A.

 

V Demand = Sales[1]
 

 

Sub-dimensions can also be referenced. In this example Y is set to a one-dimensional array of two elements, while Z is set to a two dimensional array, but with only 3 rows instead of 5.

 

V X[5,2] = {{100,200}, {100,200}, {100,200}, {100,200}, {100,200}}

V Y[2] = X[1,*]

V Z[3,2] = X[1..3,*]
 

 

In the examples above, all the array references are actual numbers. However, array references can also be other Forio variables.

For example:

 

V MyIndex = 2

V MyArray = {10,11,12}

V MyReference = MyArray[MyIndex]
 

 

Arrays can even contain equations or functions as in these examples.

In the first example, the item at the index MyIndex + 1 is returned.

 

V MyReference2 = MyArray[MyIndex+1]
 

 

In the second example, each simulation step a new item from DataSeries is returned.

 

V DataSeries = {100,101,102,102,104}

V MyValue = DataSeries[SimStep]
 

 

And lastly, array references can refer to themselves, as long as they do not cause a circular reference error.

For example, a Fibonacci series is generated when each item adds the previous two items.

 

V Fibo[1..5] = {1, 1, Fibo[1] + Fibo[2], Fibo[2] + Fibo[3], Fibo[3] + Fibo[4]}
 

 

 

Array Functions

Forio provides a set of functions specifically dedicated to working with arrays.

 

Assuming that the following equation has been set:

 

V ProductSales = {500,200,100,200,400}
 

 

 Here are some examples of their use:

Equation

Result

Comment

ARRAYSUM(ProductSales)

1400

 

ARRAYAVG(ProductSales)

280

 

ARRAYMIN(ProductSales)

100

 

ARRAYMAX(ProductSales)

500

 

ARRAYSORT(ProductSales)

{100,200,200,300,500}

 

INDEXOF(200, ProductSales)

2

 

INDEXOF(200, ProductSales,3)

4

The 3 indicates the search should start at the third index

INDEXOF(199,ProductSales,3)

NaN

The NaN (Not a Number) indicates that 199 was not found.

 

The array functions also work with multiple dimensions

Equation

Result

Comment

ARRAYSUM({{100,200}, {100,200}, {100,200})

1400

Sums all elements of this two-dimensional array

ARRAYSUM({{100,200},{100,200}, {100,200}[*,*])

280

Does the same, but explicitly shows the dimensions it is summing over.

ARRAYSUM({{100,200},{100,200}, {100,200}[2,*])

300

Sums the second {100,200}

ARRAYSUM({{100,200},{100,200}, {100,200})[*,2])

600

Sums the second element (200) of each of three sub-arrays.

 

The following example assumes that ProductSales is defined as below.

 

V ProductSales[2,5] = {{500,200,100,200,400},{100,200,300,200,100}}
 

 

To sum an array across one of multiple dimensions, combine ARRAYSUM with the FOREACH statement.

Equation

Result

Comment

ARRAYSUM(ProductSales)

2300

Sums all elements

ARRAYSUM(ProductSales[*,*])

2300

Sums all elements, explicitly noting the dimensions

FOREACH(row,1..2,
ARRAYSUM(ProductSales[row,*]))

{1400,900}

Constructs a new array, with each item being the sum across the given row.

FOREACH(col,1..5,
ARRAYSUM(ProductSales[*,col]))

{600,400,400,400,500}

Constructs a new array, with each item being the sum across the column.

 

Working with Enumerated Ranges

Usually models use integers as indices to the arrayed elements. However, Forio Equations also allow enumerated ranges which permit array indices to be named instead of numbered. An enumerated range contains enumerated items that can be used as array indices. Using enumerations can help modelers develop more understandable models.

To use an enumerated item, the modeler must define an array range with an "R" statement. Then, this range can be used in equations. Back to the example from the beginning.

 

R Products = books, cds, games

D Price[Products] = {100,150,175}

V Sales[Products] = {100, 200, 150}

V Revenue[Products] = Sales * Price

V MyBookRevenue = Revenue[books]
 

 

By defining each of these variables to be arrayed over the same range, we can combine Price and Sales to make Revenue, and then refer to the books index of Revenue.

Combining Arrays with Different Dimensions

Often, it is not enough to use an arrayed element in which all elements in the equation have the same dimension. Instead, the modeler may want to combine arrays of different ranges. The way to do this is with a FOREACH statement.

 

R Products = books, cds, games

R Market Segments = 1..2

V Market Size[Market Segments] = {1000,2000}

V Market Share[Products, Market Segments] = {{20%, 30%}, {22%, 33%}, {44%, 46%}}

V Our Market[Products, Market Segments] =
    FOREACH(p, Products,
               FOREACH(m, Market Segments,
                          Market Share[p,m] * Market Size[m]
               )
    )
 

 

The equation for Our Market is arrayed over Products and Market Segments. The two FOREACH statements construct that array, applying the given expression to each new array item. This can be thought of in English as "For each product p and each market segment m in the result, the formula is Market Share[p,m] times Market Size[m]".

This powerful structure can be used to combine arrays of any dimension.