Difference between revisions of "Tutorial: Arrays"
DKontotasiou (talk | contribs) |
DKontotasiou (talk | contribs) |
||
Line 115: | Line 115: | ||
Open the Definition field and select [[File:Chapter_5.6-updated.png]] from the Expression popup menu. Enter the new definition as shown above (blue text). | Open the Definition field and select [[File:Chapter_5.6-updated.png]] from the Expression popup menu. Enter the new definition as shown above (blue text). | ||
+ | |||
+ | ==Combining arrays== | ||
+ | Now that you have established purchase and lease payments, you can combine them in one variable. This time the index will be '''Finance Option'''. | ||
+ | |||
+ | :'''Variable Payments := <span style="color: blue">Table (Finance_option)(Car_price, Lease_payment)</span>''' | ||
+ | |||
+ | Create a new variable titled '''Payments'''. | ||
+ | |||
+ | Open the definition field and select '''''Table''''' from the Expression pop-up menu. | ||
+ | |||
+ | The Indexes window appears. Select the Finance option index and transfer it to selected indexes list. Click '''OK'''. An edit table will appear. | ||
+ | |||
+ | [[File:Chapter_5.7-updated.png]] | ||
+ | |||
+ | You may have noticed an important difference between this table and the previous tables. In the previous tables you entered number values into the table cells, but this time you are entering expressions! Expressions are valid entries for table cells. With very few exceptions they can be as complex as anything you might enter in a standard definition line, including formulas, logical expressions and conditional expressions. You will see more examples of this later in the chapter. | ||
+ | |||
+ | Now look at the result of this new variable. | ||
+ | |||
+ | Select the '''Payments''' variable and click the Results button ([[File:Chapter_4.54-updated.png]]) | ||
+ | |||
+ | Something interesting has happened! Notice that the array contains two dimensions even though only one index is called out in the definition of the array: | ||
+ | |||
+ | :'''Variable Payments := <span style="color: blue">Table (Finance_option)(Car_price, Lease_payment)</span>''' | ||
+ | |||
+ | Why is '''Car type''' included in the result when '''Finance_option''' is the only index included in the definition of the table? | ||
+ | |||
+ | The '''Car type''' index is included because it is an index of the input variables '''Car price''' and '''Lease payment'''. | ||
+ | |||
+ | You have just encountered one of the most powerful features of Analytica’s array abstraction: The dimensions of arrayed input variables will automatically be incorporated into the resulting output of an expression. The general principle of array abstraction can be summarized as follows: | ||
+ | |||
+ | '''In Analytica, the result of an expression is arrayed by the ''union'' set of dimensions from all input variables, and the definition of the expression itself.''' | ||
+ | |||
+ | ==Adding a new dimension to an array== | ||
+ | So far, the Payments variable is not very useful for comparing the purchase and lease options. Lease payments are paid every month instead of just once, and there is still ownership equity to consider. In order to represent payments as a stream of cash flows over time, you will need to add a new dimension to the Payments array: | ||
+ | |||
+ | Create and define a new index titled Period. Define it as a sequence of months from 0 to 24. | ||
+ | :'''Index Period := <span style="color: blue">Sequence(0,24)</span>''' | ||
+ | |||
+ | ---- | ||
+ | There is a special shortcut syntax for sequences that have a step value of one: Type the starting value, followed by two periods (..), followed by the final value. For example, the '''Period''' index can be defined as: Index Period := <span style="color: blue">0..24</span> | ||
+ | ---- | ||
+ | |||
+ | Next, you will edit the '''Payments''' definition to include the new index. Try using the edit table for this: | ||
+ | |||
+ | [[File:Chapter_5.8-updated.png]] | ||
+ | |||
+ | There is a button in the top left corner of the edit table, labeled with a parallelogram. Click this button to open the Indexes window. Then add '''Period''' to the list of selected indexes. | ||
+ | |||
+ | [[File:Chapter_5.9-updated.png]] | ||
+ | |||
+ | The edit table should now look like this: | ||
+ | |||
+ | [[File:Chapter_5.10-updated.png]] | ||
+ | |||
+ | The subset of an array corresponding to a singe index value is referred to as a ''slice''. When you expanded the '''Payments''' array to include a new index, the original values (expressions in this case) were copied into all new slices along the '''Period''' index. | ||
+ | |||
+ | The '''Payments''' array is not yet accurate. Under the Purchase column you should have zero values for all periods except Period 0. Lease payments should be included in periods 1 through 24 but not Period 0. It would not take too much effort to edit all the cells to be the way you want them to be. The final definition of the array would look something like this: | ||
+ | |||
+ | [[File:Chapter_5.11-updated.png]] | ||
+ | |||
+ | Although this would work, it would not be a very efficient approach. In general, whenever you find yourself editing tables in the same way you would edit a spreadsheet, you are not benefiting from the advantages of array abstraction. | ||
+ | |||
+ | ==Using conditional expressions== | ||
+ | Expressions can include conditional statements using If...then...else syntax. The condition can be based on a variable or an index value. This is a very useful way of defining array variables. For example, the cash flow for purchasers can be represented as: | ||
+ | |||
+ | :'''If Period = 0 then Car_price else 0''' | ||
+ | |||
+ | Likewise, the cash flow for lease holders can be represented as: | ||
+ | |||
+ | :'''If Period = 0 then 0 else Lease_payment''' | ||
+ | |||
+ | Specifying a condition based on '''Period''' will automatically add the '''Period''' index to the array. This would have been a better way to add a new dimension to the '''Payments''' variable, compared to the example above. | ||
+ | |||
+ | Let’s revert the Payments variable to the way it was before adding the Period index: | ||
+ | |||
+ | :'''Variable Payments := <span style="color: blue">Table(Finance_option)(Car_price, Lease_payment)</span>''' | ||
+ | |||
+ | As you did in the section above, Select the '''Payments''' variable, open the edit table, and click the Index button in the top left corner. | ||
+ | |||
+ | Select the '''Period''' index in the Selected Indexes list and transfer it back to left hand box. Click '''OK'''. Answer '''Yes''' when the warning appears: | ||
+ | |||
+ | [[File:Chapter_5.12-updated.png]] | ||
+ | |||
+ | [[File:Chapter_5.13-updated.png]] | ||
+ | |||
+ | This time you will add the '''Period''' index by including it in a conditional expression. Edit the cells to include conditional expressions: | ||
+ | |||
+ | :'''Variable Payments := <span style="color: blue">Table(Finance_option) | ||
+ | :(If Period = 0 then Car_price else 0, | ||
+ | :If Period = 0 then 0 else Lease_payment)</span>''' | ||
==See Also== | ==See Also== |
Revision as of 09:06, 1 July 2015
This chapter shows you how to:
- Create and define an Index
- Define an array variable as a Table
- Understand principles of array abstraction when combining arrays in an expression
- Use conditional expressions and logical values when defining an array
- Define variables using Expression syntax
- Use local variables to simplify an expression
- Analyze a multi-dimensional result by pivoting indexes
- Reduce an array using subscripts
- Use array reducing functions such as Sum() and NPV()
This chapter demonstrates Intelligent Arrays, one of the most powerful features of Analytica. An array can be generally defined as a variable to which multiple values are assigned simultaneously. For example, in the previous chapter you assigned a list of values to a single variable, Miles per gallon. This is an example of a simple one-dimensional array. When you defined Fuel cost using the Miles per gallon array variable as an input, it also became an array. This demonstrates the concept of array abstraction. Array variables can be used just like ordinary variables in expressions. Whenever you expand an index of the array to include more values, or even add an entirely new index along a new dimension, all dependent variables downstream will be extended automatically! Intelligent arrays allow you to scale your model without making any changes to the design.
This Chapter is rich in content and covers lots of ground. The example model is still somewhat simplified, but it is chosen to be complex enough to demonstrate as many important array concepts as possible. The workflow will be streamlined to allow you to concentrate on the ideas with-out getting bogged down with procedural details. Therefore, you should already be familiar with the basic mechanics of Analytica‘s user interface.
The prerequisite skills include:
- Creating a new model; Opening an existing model; Save; Save As... (See Chapter 1)
- Creating and defining new variables; Entering attributes in Attribute or Object windows; Drawing influence arrows between nodes. (See Chapter 4)
Summarizing variables using Expression syntax
Although Analytica offers a convenient and visually intuitive interface with which to define variables, it is often helpful for users to be able to enter definitions directly using Expression syntax. Every variable type and every functional expression can be represented this way. In addition to its usefulness in building models, expression syntax is a convenient and efficient way to summarize examples in the documentation. This efficiency is evident in the following four-line summary of the Car cost model from the previous chapter:
- Variable MPY := 12K
- Variable MPG := Sequence(20,50,5)
- Variable Fuel_price := 3
- Variable Fuel_cost := MPY*Fuel_price/MPG
In order to expedite the process of building the model, we will summarize new variables in this for- mat throughout the rest of this chapter. It is useful to be familiar with Expression syntax since you will also see it in User Guide and Wiki examples:
- The first term indicates the Class of the object being defined. There is a Class identifier for each type of node found in the node palette. These include: Decision, Variable, Chance, Objective, Module, Index, Constant and Function
- The second term contains the Identifier for the object. (Keep in mind that identifiers are not allowed to contain spaces.)
- A colon followed by a equal sign (:=) is referred to as the assignment operator.
- The expression to the right of the assignment operator defines the object. Conveniently, this portion of the summary line exactly matches the syntax that Analytica requires in the definition field. In fact, you can copy this directly into Analytica if you wish! For your convenience, the portions of the summary line that can be copied into the definition field will be highlighted in blue.
Fast Tony’s Generic Wheels
In this chapter you will extend the Car cost model to address an important decision scenario: the purchase of a new car. There are three cars to choose from: Standard, SUV and Hybrid.
There are also three finance options: Cash purchase, Lease, or Loan. As you can see, Fast Tony has presented you with an array of decision possibilities, a 3 x 3 array to be exact. Your objective is to determine the option with the lowest total cash outflow over a 24-month period, including fuel. (Maintenance costs are covered under warranty as long as Fast Tony’s cousin, Greasy Tony, is on his feet that day.) Ownership equity will be represented as a positive cash flow on the last period.
Continue with model
In this chapter, you will continue with the model you developed in Chapter 4. The model from the end of Chapter 4 can be found in the Tutorial Models directory:
Creating an index variable
Index variables define the categories along a dimension of an array. They are represented by index nodes (parallelogram shapes) in the influence diagram. In this example, your decision will be arrayed by Car type and Finance Option so you will need to define an index for each of these dimensions. Index variables are generally defined as a list of labels or a list of values representing categories in the array.
(For the finance options you will leave out "Loan" for now. It will be added later.)
- Index Car_type := ['Standard','SUV','Hybrid']
- Index Finance_option := ['Purchase','Lease']
As an alternative to selecting List of Labels in the Expression pop-up menu, you can select () and enter the definition directly using Expression syntax. Simply list the values separated by commas and encase them in square brackets [ ]. Note that all text values in Expression syntax must be enclosed in quotes (single or double).
Defining a variable as a table
Each of the cars has a unique purchase price. You will define Car price as a Table indexed by Car type. In this context, a "table" does not necessarily have two dimensions. It can have one (as in this case), two, three or more.
- Variable Car_price := Table(Car_type)(22K,40K,24K)
After you close the Indexes window an edit table will appear.
Enter the following values for Car price:
- Standard: '22K'
- SUV: 40K'
- Hybrid: '24K'
You can draw influence arrows from index nodes to table variables to pre-populate the Indexes window with the chosen indexes. Influence arrows from index nodes are invisible by default but can be made visible by choosing the Diagram menu and selecting Set diagram style.
Next you will create a variable for lease payments. Fast Tony lists the following monthly payments for the two-year lease option:
- Standard: '$400'
- SUV: $700'
- Hybrid: '$500'
Lease Payment is similar to the Car price variable. But this time you will enter the definition directly using expression syntax instead of using the edit table.
- Variable Lease_payment := Table(Car_type)(400, 700, 500)
As you can see, Table definitions follow a specific syntax. The Table declaration is followed by two lists enclosed in parentheses. The first list contains the indexes by which the table will be arrayed. (In this simple example there is only one index but there can be many.) The second list contains the values.
It is important for the values to be in the same order as the index categories. Recall that the Car type index was defined as:
- Index Car_type := ['Standard','SUV','Hybrid']
which matches the respective order of values in the Lease payment variable. The same principle applies when there is more than one index. For example, a two dimensional array might look like:
- Table (Index_abc, Index_123)
- ('a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3')
It is generally easier to use an edit table when multiple dimensions are involved.
Finally, re-define the existing Miles per gallon variable as a table indexed by Car type. The MPG values for Standard, SUV and Hybrid are 28, 23, and 45 respectively.
- Variable Mpg := Table(Car_type)(28, 23, 45)
Select the Miles per gallon variable.
Open the Definition field and select from the Expression popup menu. Enter the new definition as shown above (blue text).
Combining arrays
Now that you have established purchase and lease payments, you can combine them in one variable. This time the index will be Finance Option.
- Variable Payments := Table (Finance_option)(Car_price, Lease_payment)
Create a new variable titled Payments.
Open the definition field and select Table from the Expression pop-up menu.
The Indexes window appears. Select the Finance option index and transfer it to selected indexes list. Click OK. An edit table will appear.
You may have noticed an important difference between this table and the previous tables. In the previous tables you entered number values into the table cells, but this time you are entering expressions! Expressions are valid entries for table cells. With very few exceptions they can be as complex as anything you might enter in a standard definition line, including formulas, logical expressions and conditional expressions. You will see more examples of this later in the chapter.
Now look at the result of this new variable.
Select the Payments variable and click the Results button ()
Something interesting has happened! Notice that the array contains two dimensions even though only one index is called out in the definition of the array:
- Variable Payments := Table (Finance_option)(Car_price, Lease_payment)
Why is Car type included in the result when Finance_option is the only index included in the definition of the table?
The Car type index is included because it is an index of the input variables Car price and Lease payment.
You have just encountered one of the most powerful features of Analytica’s array abstraction: The dimensions of arrayed input variables will automatically be incorporated into the resulting output of an expression. The general principle of array abstraction can be summarized as follows:
In Analytica, the result of an expression is arrayed by the union set of dimensions from all input variables, and the definition of the expression itself.
Adding a new dimension to an array
So far, the Payments variable is not very useful for comparing the purchase and lease options. Lease payments are paid every month instead of just once, and there is still ownership equity to consider. In order to represent payments as a stream of cash flows over time, you will need to add a new dimension to the Payments array:
Create and define a new index titled Period. Define it as a sequence of months from 0 to 24.
- Index Period := Sequence(0,24)
There is a special shortcut syntax for sequences that have a step value of one: Type the starting value, followed by two periods (..), followed by the final value. For example, the Period index can be defined as: Index Period := 0..24
Next, you will edit the Payments definition to include the new index. Try using the edit table for this:
There is a button in the top left corner of the edit table, labeled with a parallelogram. Click this button to open the Indexes window. Then add Period to the list of selected indexes.
The edit table should now look like this:
The subset of an array corresponding to a singe index value is referred to as a slice. When you expanded the Payments array to include a new index, the original values (expressions in this case) were copied into all new slices along the Period index.
The Payments array is not yet accurate. Under the Purchase column you should have zero values for all periods except Period 0. Lease payments should be included in periods 1 through 24 but not Period 0. It would not take too much effort to edit all the cells to be the way you want them to be. The final definition of the array would look something like this:
Although this would work, it would not be a very efficient approach. In general, whenever you find yourself editing tables in the same way you would edit a spreadsheet, you are not benefiting from the advantages of array abstraction.
Using conditional expressions
Expressions can include conditional statements using If...then...else syntax. The condition can be based on a variable or an index value. This is a very useful way of defining array variables. For example, the cash flow for purchasers can be represented as:
- If Period = 0 then Car_price else 0
Likewise, the cash flow for lease holders can be represented as:
- If Period = 0 then 0 else Lease_payment
Specifying a condition based on Period will automatically add the Period index to the array. This would have been a better way to add a new dimension to the Payments variable, compared to the example above.
Let’s revert the Payments variable to the way it was before adding the Period index:
- Variable Payments := Table(Finance_option)(Car_price, Lease_payment)
As you did in the section above, Select the Payments variable, open the edit table, and click the Index button in the top left corner.
Select the Period index in the Selected Indexes list and transfer it back to left hand box. Click OK. Answer Yes when the warning appears:
This time you will add the Period index by including it in a conditional expression. Edit the cells to include conditional expressions:
- Variable Payments := Table(Finance_option)
- (If Period = 0 then Car_price else 0,
- If Period = 0 then 0 else Lease_payment)
See Also
Tutorial Chapter 4 <- | Working with Arrays (Tables) | -> Creating the Party Problem Model |
Enable comment auto-refresher