Choice
Choice(i, n)
Choice displays a drop-down menu to allow an end user to select from a list of options. The index i is the list of options and n is the position of the currently selected option in that list. When the user selects a different option, it changes the value of n. You can use Choice to provide a menu as the definition of a variable or in a cell of an Edit table (or ProbTable or DetermTable). Choice must be the top level of the definition or the cell, and may not be nested within an expression. You must create an Input node for the variable before it will display choices as menus.
Choice option All
By default, the menu will include All as the first option. If you choose All, the result will be computed for each value of index i. This makes it easy to do a parametric analysis to see how the choices affect the results. When you choose All, it sets parameter n to 0.
If you select All for multiple Choice menus, results will be computed for all combinations of values from those menus. Each selection of All may add an index dimension to the results. So if there are more than two or three, the number of dimensions may make the result hard to understand, and long to compute. In a few cases, the model may not be able to compute correctly with All. In such cases, you can turn off All as an option by setting an optional third parameter, inclAll to false (0). It usually advisable to set inclAll to false whenever you use Choice in an Edit table.
Suppose multiple variables use Choice(I, n) with the same index I, and you choose All for each of them, e.g.
Index I := ['Low', 'Mid', 'High'] Variable A := Choice(I, 0) Variable B := Choice(I, 0) Variable Result := IF A = 'Low' AND B = 'Low' THEN 0 ELSE 100 --> Array(I, [0, 100, 100])
Result is indexed by I only once, and A and B are treated as if they have the same values. If you wanted to vary them independently, they should use different indexes, e.g.
Index I := ['Low', 'Mid', 'High'] Variable A := Choice(I, 0) Index J := CopyIndex(I) Variable B := Choice(J, 0) Variable Result := IF A = 'Low' AND B = 'Low' THEN 0 ELSE 100 --> Array(I, J, [0, 100, 100], [100, 100, 100], [100, 100, 100])
The function CopyIndex(I) makes returns a new index with the same values as I.
Declaration:
Choice( I : Index ; n : atomic nonNegative ; inclAll : optional boolean = True ; Eval : optional boolean = True ; Result : optional Array[I] )
where
- I : An index containing the values appearing on the popup. When I:Self, the values listed in the variable's domain are used.
- n: The position of the current selection, or 0 for "All". This should always be an explicit integer, not an expression.
- inclAll: (default True) Specifying whether the "All" option is displayed.
- Eval: (new to 4.0) Specifies whether variable or expression terms are evaluated for the return value.
- Result: (new to 4.0) Specifies a return value for each choice different from the value in I.
The Eval parameter has no effect when the Result parameter is specified, or when I contains only constants, such as numbers and text strings. Setting Eval to false is recommended in most cases when I constains varTerms (variable identifiers).
When a users changes the selection using the dropdown, the second parameter in the definition is replaced with the new choice.
Self-Indexed Choices
When a variable is defined with the first parameter set to Self, as in the definition:
Choice( Self, 0 )
then the set of values appearing in the choice are located in the variable's own domain attribute. In this case, the domain must be either a list, list-of-labels or index type.
The easiest way to create a Self-Choice is to select "Choice..." from the definition type popup. Analytica will then fill in a default one-element list-of-labels selection.
When a domain is a list, the elements are usually numbers, but may also be variable identifiers or expressions. (See "Identifier and Expression items" below).
(new to 4.0) If you use an Index domain, then the values for domain of Self come from another index variable. In this case, Choice(Self,1) when domain=I is very similar to Choice(I,1) with no domain set. There are, however, several differences. First, if you use an index domain, then your variable will have both an index value and mid/prob values, while if you use Choice(I,1) your variable will not have an index semantics. Second, if "All" is selected in the pulldown, the result of Choice(I,0) is indexed by I, while Choice(Self,0) is indexed by Self. Third, in an index domain using Index I, the values in the domain are the evaluated values of I. If I contains only numbers and text strings, then these are the same as the values of I, but if I contains identifiers or expressions, then there is a difference. Choice(I,1) would show the identifiers or expressions, while Choice(Self,1) with domain=I would show the values of those variables in the pulldown.
Input Nodes
Selecting "Make Input" from the Object menu creates a pull-down control that you can position on your diagram as part of a user-interface form.
Pull-downs in edit tables
(new to 4.0)
You can define an edit table cell using the Choice function. This is a useful way to restrict the possible values your users can enter into the cell.
When you are in edit mode, the expression is shown, allowing you to edit the definition.
When the edit table is viewed from browse mode, a pulldown control appears in the cell. If your table does not have an input node associated with it, then the table itself is read-only and the value cannot be changed. Thus, when you are using Choice cells, you will usually create an input node for your edit table. When an edit table with an associated input node is viewed, choice cells display active, changeable pulldown controls.
Likewise, choice cells can also appear in DetermTables, ProbTables and Subtables.
In most cases, when choice is used in a a table cell, you will probably want to set the InclAll parameter to false, so that a new dimension is not introduced into the entire table from that one cell selection.
Using Choice with DetermTable
A useful arrangement is to use Choice variables for key parameters, especially parameters where you may want to perform a parametric analysis (by selecting "All"), and then organizing tabular data in DetermTables (rather than standard edit Tables). This arrangement looks like the following:
Decision Scenario := Choice(Self,0) Domain of Scenario : [1,2,3,4] Variable A := DetermTable(Scenario)(...)
In this arrangement, the definition of A appears as an edit table, indexed by all domain values of Scenario. However, when evaluated, only the selected row is returned.
With this arrangement, you can compute downstream results for a single Scenario (or other dimension), or for every scenario when "All" is selected. When available memory limits your ability to perform a full parameter analysis across many dimensions (since the number of combinations increases multiplicatively), this setup makes it easy to limit the parametric analysis to only selected dimensions.
A second variation on this is:
Index AllScenarios := [1,2,3,4] Decision Scenario := Choice(Self,0) Domain of Scenario : Index AllScenarios Variable A := DetermTable(Scenario)(...)
Identifier and Expression Items
When an item of an index or list domain that is used by Choice is a variable identifier, then the pulldown will display either the title of the object or its identifier, depending on whether "Show By Identifier" is selected. The "Show By Identifier" setting is found on the Object menu and can also be toggled by pressing CTRL-Y.
When a variable identifier item is selected, the result of evaluating the Choice function will be the result of evaluating that variable unless the Eval or Result parameters are specified.
(new to 4.0) If Eval is set to false (it defaults to true), then an object handle of the variable is returned. If you are dealing with Choices involving variable identifiers, using Eval:False is generally preferred. Operations such as comparing the selected value to the original index, or use of a determTable based on the choice variable, function more consistently and less ambiguously. As a comparison, if you return values (e.g., Eval:True), and two variables in the choice happen to have the same value, then an ambiguity over which variable was selected exists, but with Eval:False no such ambiguity exists.
Using The Result Parameter
(new to 4.0)
The Choice function has an optional parameter, Result, that can be used to specify the value returned when Choice is evaluated in a completely general manner. Using the Result parameter, the result of evaluating Choice can be totally separate from the value appearing on the pull-down itself.
Choice normally returns the selected index label. The following syntax returns the index position (rather than label) of the selected value:
Choice( I, 1, Result: @I )
Suppose you have a table A indexed by I, and you want your user to select a row of I, and then select out only the selected row. A standard formulation of this is:
Variable A := Table(I)(...) Decision selectedRow := Choice(I,1) Variable selectedA := A[I=selectedRow]
Using the Result parameter, a variable can be eliminated:
Variable A := Table(I)(...) Decision selectedA := Choice(I,1,Result:A)
When the Result parameter is specified, the Eval parameter does nothing.
See Also
- Checkbox
- Webinar on Creating Control Panels
Enable comment auto-refresher