# The domain of possible values

## Domain Attribute

The Domain Attribute specifies the set or range of allowed values for a variable. It can be a list of numeric or text values (a list of numbers or list of labels). Or for number it can specify the upper and/or lower bound. You aren't required to specify a Domain for every variable, although it's often a good idea to do so before you specify its Definition to help you think clearly about what the variable represents. It also helps Analytica display results and detect errors -- for example, if it the definition results in a value outside the Domain.

The Domain specifies the set or range of values allowed in each cell of an Array. It does not constrain its dimensions or indexes.

**Making the Domain visible**: By default, it doesn't show the Domain attribute in the Object Window (except that in Analytica Optimizer, it is always visible for Decision variables). You can make it visible by placing a check next to **Domain **in the Attributes dialog from the Object menu. You must be in edit mode to make this change.

## Domain Types

The pulldown menu for domain attribute pulldown offers several types of Domain:

The top group lets you specify an implicit set of values, such as all integers above zero. The second group specifies an explicitly enumerated set of discrete values. And the final type, **Expression**, lets you specify the domain as a computed expression, which provides complete generality for the most advanced users. Each type has additional subfields for information such as bounds.

**Automatic**: Automatic signifies that you have not specified the domain explicitly. In that case, Analytica uses heuristics to infer the likely domain based on the information at hand. For example, it tries to guess whether a variable is continuous or discrete to display a probability distribution as a probability density graph (if it's continuous) or probability mass function (it it's discrete). In case it doesn't guess right, you can specify the Domain as Continuous or Discrete so it does what you want.

**Continuous**: Indicates that the variable is real-valued. For this Domain type, you may optionally specify the lower and/or upper bounds:

If you specify bounds, you should treat these as hard bounds, meaning the final value should never fall outside the indicated range. If, for example, you have an uncertain variable with a right tail, you would leave the upper bound blank.

**Integer**: Indicates that the variable is integer-valued, with optional lower and upper bounds.

**Grouped Integer**: This option shows up only for decision variables when using the Analytica Optimizer. Each grouped integer variable belongs to a named group. The optimal value for cells falling within a given group must have a value between 1 and *N*, where *N* is the total number of cells belonging to the same group, and such that all cells belonging to the same group have a different value. This category is used solely for formulating certain types of optimization problems. See the Analytica Optimizer Guide.

**Boolean**: Indicates that the variable is 0 or 1 valued (False or True).

**Discrete**: Indicates that the variable is discrete (as opposed to continuous), but not captured by the above Integer or Boolean categories, and where the set of discrete values cannot be enumerated explicitly. The discrete type pulldown allows you to designate the values further as being textual, numeric, or more Any (unrestricted).

When an input control is set to **Discrete Text**, quotation characters do not display around the current value, and whatever a user types is taken directly as text. No attempt is made to parse the entry as a number, variable name or expression.

Some uncertain quantities result in discrete numeric (but non-integer) outcomes. When **Discrete Numbers **is selected, probability distribution graphs will be displayed, not probability density graphs.

**Explicit Values**: This option allows you to list the set of possible (allowed) values explicitly. As with discrete, you can indicate whether the values are all numeric or all textual.

**Copy From Index**: Indicates that the set of allowed values are the set of values found in another index variable. When you select this option, you are asked to select the index. To change the source index, click on the index name.

**Expression**: (*Advanced*) This view allows you to enter the domain as an Analytica expression, or to view the expression for the currently selected domain option. This provides a high degree of flexibility for advanced scenarios, allowing the domains themselves to be computed, array-valued, and conditional. Expression mode is also required to access certain less common parameters of the above domain types.

There are five special domain functions which are used to specify each of the above domain types in expression view, Continuous(), Integer(), GroupedInteger(), Boolean(), and Discrete(). The simplest domain expressions consist of a single call to one of these functions, e.g.:

`Continuous(lb: 0, ub: 1000)`

These functions can be combined in arbitrary ways using Analytica expression syntax to create computed domains. For example:

`If Col = "Id" then Integer(lb: 1) Else Continuous(lb: low, ub: low + range)`

An expression can compute a set of discrete values as an unindexed list, or it can wrap them in a call to the Discrete() function, e.g.:

`Discrete("Accounting", "Engineering", "HR", "Marketing", "Sales")`

Each standard domain type considers null values to be acceptable. You can override this and indicate that null is not acceptable by specifying an optional «nullOk» parameter as `false`

in expression view, e.g.:

`Continuous(nullOk: false)`

Each of the five functions are described in Domain Functions below.

As a stylistic guideline, domain computations should be designed to be computationally simple. For example, although possible, it is generally not a good idea to employ a complex and time consuming algorithm that produces a highly informed and nearly tight lower bound. Instead, utilize a “hard” bound that is relatively easy to obtain and save the complex algorithms for variable definitions.

## Uses of Domain

When the domain is specified, Analytica makes use of the information in numerous ways.

**Bounds checking**: When the value of a variable is computed, it is compared with the domain, and if the result is not consistent with the domain, an out-of-range warning is displayed. Bounds violation are often effective in detecting modeling mistakes. The **Check value bounds...against domain bounds **preference setting disables this feature (see Preferences dialog).

**Detecting Logical Errors**: The domain enables Analytica to detect and warn of various inconsistencies in your model that may indicate an error in your modeling logic. Sometimes inconsistencies arise when one part of a model is changed, but you forget to change another part of your model to be consistent. Analytica will display warning messages when these situations are encountered, which can help to cut down on undetected modeling errors. An example is the following. Suppose an expression contains the following sub-expression

`If X = "Yes" Then...`

where the `domain of X`

is `Boolean`

, meaning that a value of `X`

will be *0* or *1*, not “Yes” or “No”. Analytica issues a warning (at evaluation time) that reveals this error in logic, which is made possible as a result of specifying the domain.

**Interpretation of uncertainty**: The computation of probability distributions or cumulative probability distributions requires the underlying sample to be interpreted as being either continuous or discrete. Although Analytica can usually correctly infer this from heuristics that make use of various other clues, an explicit domain provides this information directly.

**Label ordering in graphs**: In parametric graphs (e.g., XY graphs, histograms of discrete quantities, etc), the ordering for labels on the graph axes is not always obvious. In the absence of guidance from the domain, Analytica will usually use a lexical sort order; however, if you want to control the ordering of possible values, you can do so by using an explicit values domain. The order that possible values are listed is then used as the label ordering on graphs.

**Search Space in Optimization**: In Analytica Optimizer, the domain of decision variables defines the search space for constrained optimization problems. See Analytica Optimizer Guide.

**List of Options for a self-Choice**: A node with a definition of `Choice(Self,...)`

uses the set of possible values listed in the domain as the options that appear on the Choice pulldown.

**Indexes for a DetermTable or ProbTable**: A DetermTable specifies a result for every possible value across a set of parent variables. The result of a determTable selects out the values that match the computed value. The domain is used to specify what the set of possible values are for each of these parent selector variables. A ProbTable behaves like a DetermTable, with its own domain included as a table index.

**Validation of user input:** When a user of a model enters values that are in disallowed by the domain, Analytica can provide the user with immediate feedback that his entry is out of the allowed range. This can be utilized in input controls or edit table cells.

**Display and parsing of textual values**: The domain influences how values are shown in input fields or cells. Should quotes be displayed around textual values? They will be if the domain indicates that both numeric and textual values are acceptable, but not if the variable is restricted to textual values. What if the user enters text that matches an existing variable name, or text that could be interpreted as a number? Should it be treated as a purely textual entry, or should it be parsed? Again, this is determined by the domain. When the domain is restricted to purely textual values, the entry is treated purely as text.

## Domain Functions

(*Advanced*) The functions in this section are used in the Expression view of the Domain attribute to specify the space of possible values for a variable.

It would be highly unconventional to use any of these domain functions from outside of the domain attribute; nevertheless, it is possible to do so. When a domain function is evaluated, the return value is in the form of a parsed expression, consisting of a function call to the indicated function, but with each parameter evaluated and replaced by the literal values. Treating this result as an atomic value, expressions can assemble heterogeneous arrays of domain types that vary across multiple indexes.

**Continuous( lb, ub, orZero, nullOk)**: Used to specify a continuous domain. The optional «lb» and «ub» parameters specify lower and upper bounds respectively, and the expressions specified for «lb» and «ub» may evaluate to an array when the bounds vary along an index. The «orZero» parameter may be set to true to specify a semi-continuous domain, in which zero is acceptable along with any value consistent with «lb» and «ub». By default, null values are considered acceptable, but when «nullOk» is specified as

`false`

, then Null value will trigger out-of-bounds warnings. See also Continuous().
**Integer( lb, ub, nullOk)**: Used to specify an integer domain. The optional «lb» and «ub» parameters specify lower and upper bounds respectively. Values equal to the bounds are considered to be within the acceptable range. The «nullOk» parameter can be set to

`false`

to reject null values as out-of-range. When not specified, «nullOk» defaults to true. See also Integer().
**GroupedInteger( groupName, .., nullOk)**: Used to specify a grouped integer domain, in which all cells belonging to the same group are required to have a unique value in the final solution found by optimizer. This option is generally only used from Analytica Optimizer, and only in the context of an integer programming problems. See also GroupedInteger().

**Boolean( nullOk)**: Indicates a 0-1 valued domain. Any value other than 0, 1 or Null will trigger an out-of-bounds warning. When the optional «nullOk» parameter is specified as

`false`

, then Null will also trigger an out-of-bounds warning. See also Boolean().
**Discrete( x1, x2, x3,..., type, nullOk)**: This function is used to encode both a

**Discrete Domain**with unknown values, and the

**Explicit Values**domain where the values are explicitly listed. For an Explicit Values domain, the values are listed as the parameters to the function, e.g.:

`Discrete(2, 3, 5, 7, 9, 11, 13, 17)`

For an implicit discrete domain, no allowed values are listed. Either usage may include the «type» parameter, which must be specifying using the named parameter convention and may be specified as any of the following values, or a list of any of the following values: `"Any", "Number", "Text"`

or `"Handle"`

, e.g.:

`Discrete(Type: "Text")`

See also Discrete().

The type setting is used by the user interface components when labels are being entered to determine whether the values should be parsed. Expressions are allowed in GUI list cells when the type is `"Any"`

.

Null values are also accepted without generating an out-of-bounds warning unless `nullOk: False`

is specified.

## Array-valued domains

It is possible to set the Domain attribute value to an array of domains, such that a different domain applies at different coordinates. Here are some scenarios where this is useful:

- In an optimization problem, some slices of a Decision variable are integer-valued while other slices are continuous.
- The domain can be used to validate results, which helps to detect mistakes that get introduced into you model. The legal range may vary with slice, so that different slices have different domains.
- In an edit table, the set of Choice options might be different in different slices. Of course, this can also be done more simply using different Choice expressions that use different indexes in the first parameter, and also the use of a MultiTable may be a better option. However, occasionally cases arise where the only way to pull this off (especially with computed domains) is with Self-choices and an array-valued domain.

To create an array-valued domain, create an array of domain functions, Discrete, Continuous, Integer, Boolean, or GroupedInteger, as described in the previous section. You will set the Domain type to *expression* and enter the expression that computes the domain array. It is better to compute the array-valued domain in a separate variable and just enter the variable name as the expression. This is better because it let's you inspect the domain value, and it caches the value which can have big implications for efficiency (otherwise, it needs to recompute the array every time it looks at the domain).

Here are some examples of domain expressions that result in array-valued domains:

`If VarType='Int' Then Integer() Else Continuous()`

- In this example, a variable classifies the decision variable type. Because the variable Category is array-valued, the domain has the same indexes.

`If @Time=1 Then Null Else Local CurTime[]:=Time Do Discrete(...Subset(Time<CurTime))`

- In this example, the legal values at any given time point are time points in the past. No domain constraint is imposed on the first time point (which otherwise would have no legal values).

- A variable
`Domain_of_X`

is defined as a Table. In some cells, you enter`Discrete('Apple','Banana','Cherry')`

. In other cells you enter`Discrete('Aardvark','Bear','Cat')`

. In variable`X`

, you set the domain expression to be`Domain_of_X`

, and create an edit table with a superset of the indexes. Set the Cell Default for that table to be`Choice(Self,1,0)`

. The result is that some cells allow you to select fruits, whereas other cells allow you to select animals.

When you are considering the use of an array-valued domain in order to vary the Choice options in different cells, it is usually the case that a MultiTable (or SubTable) will provide a better and more robust solution. However, both options exist.

## See Also

- Objects and values
- Domain attribute
- The domain attribute and discrete variables
- Domain Access Functions
- Domain Expressions
- Expressions
- Expression Assist
- Attributes
- Continuous()
- Integer()
- GroupedInteger()
- Boolean()
- Discrete()
- Domain Indexes
- ProbTable
- DetermTable
- Function calls and parameters
- Preferences

Enable comment auto-refresher