Proactive Evaluation

Revision as of 20:21, 30 April 2021 by BFilstrup (talk | contribs) (The "ProactivelyEvaluate myVariable:12" was missing the 'ly' to make the command work)


By default, Analytica uses "lazy evaluation" -- it evaluates variables only when needed. Sometimes you want end users to see results as soon as they look at a user interface without having to click on [calc] buttons. You can enable this by setting selected variables or modules for "Proactive evaluation" -- so that it evaluates those results as soon as you open their user-interface diagram and recomputes them when you change a variable that influences them.

Lazy vs. Proactive evaluation

Unlike most conventional computer languages and spreadsheets, Analytica normally does lazy evaluation: it evaluates each variable only when it needs to -- e.g. when you press a Calc button for that variable to view its result, or for another variable that depends on it. After evaluating a variable, it retains (caches) its value until something that it depends on is changed, when it is reset to "uncomputed". The advantages of lazy evaluation are:

  • you don't have to wait while it recomputes results that it had computed and cached previously, unlike programs in most standard computer languages.
  • you don't have to wait while it computes results you don't need, as in a spreadsheet that normally tries to compute all values when you first load it.

When a diagram contains an input control with a Choice pulldown menu or an edit table, Analytica pro-actively evaluates any index used in the menu or edit table so that it can display them properly.

Proactive preference.png

Proactively compute user outputs

New to Analytica 6.0

When you create a user interface diagram(s) for end users using input and output nodes, by default it displays output nodes [calc] button initially. Users click the [calc] button to launch the calculation and show the result when the calculation is complete. You can changes this lazy evaluation by specifying Proactive evaluation -- so that it calculates variables immediately when the user shows the user-interface diagram. And when the user modifies any input that influences a displayed result, the result is automatically recalculated.

The downside to proactive evaluation of outputs is that if the calculation takes a long time, the calculation launches every time you change a single input. This can be a pain if you want to change several inputs and then view the result. So it's best to apply proactive evaluation only for results that can be calculated quickly -- within a few seconds.

You can set output variables for proactive evaluation at three levels:

  • Module: Applies to all user outputs on the diagram for that Module.
  • Variable : Applies to all user outputs for the variable, which may appear on different diagrams. This also causes the variable to be proactively computed when the model is first loaded.
  • User Output: Applies to a single user output node instance. If the same variable has another output node in a different diagram, viewing the other diagram won't trigger the proactive calculation. This does not cause the variable to be proactively evaluated at model load time.

You can also:

  • Proactively compute outputs only in browse mode, or in both browse and edit mode.
    Because UIs are meant to be used in browse mode, it is often helpful to keep proactive calculation off in edit mode while you are developing your model logic.
  • Proactively compute only mid values, only prob-values (uncertain or sample values), or both. If an output node is set to show a mean and you have it proactive only for mid-values, then it won't trigger. You may want to do this in some cases where a mid-value is fast, but a probabilistic simulation takes a long time.

How to configure Proactive calculation of user outputs

There isn't yet a built-in user interface to configure Proactive evaluation for your model's UI. But. there's a standard library to make it easy (compared to setting them in the Typescript Window):

  1. Select Add Library... on the File menu
  2. Select "Configure Proactive User Outputs" library to import into your model.
  3. Open the library module, where you'll find this panel:
Configure proactive configuration.png
  1. If you've added modules or user outputs since you last visited this panel, press the [Refresh] button.
  2. Press the "Which diagram" menu, which shows all modules with user outputs. Select the diagram containing the user interface.

In the image above, all probabilistic outputs in the module titled "Market model" are configured to proactively compute in both browse and edit mode. If you opt to configure at the "Variable" or "Output node only" level, it shows a third pulldown that allows you to select which variable or output to set. An output is set to proactively compute at any of these three levels, then it computes.

Errors during proactive calculations

An error or warning during a proactive calculation causes it to it quietly stop the calcualtion and show the [calc] button again. Next time you press the [calc] button, it will show you the error. After detecting an error, it won't try the calculation again until there is a change in some variable that influences it so there is a chance that the error has been fixed.

Proactive evaluation on loading a model

You can configure indexes, variables or buttons to compute (or click) when your model first loads. These are some reasons you might want to do that:

  • You want to display a message box with welcome information when a model is loaded. You could call the MsgBox() function in a proactively evaluated variable or button.
  • You want an AskMsgText dialog to ask for user name or password.
  • You want to precompute some results so that the user experiences a more snappy interaction when they start to explore the model. (The downside is that users will have to wait longer while the model is first loading.)

There isn't yet a user interface for theProactivelyEvaluate attribute, so you must set it in the Typescript Window, which you can get to by pressing F12 (or Ctrl-' ).

The ProactivelyEvaluate attribute takes a bit-field -- you set it a number which is the sum of any of these values that you want:

1 = Index Value
2 = Domain value
4 = Mid value
8 = Prob value
16 = For an edit table, accept each change to a cell as it's made, rather than waiting until user clicks the green checkmark.
32 = Evaluate the OnClick of any button or picture when the model is loaded.
64 = Proactively evaluate output node in edit mode. (If unset, it does it only in browse mode)

To configure a button with the identifier do_init to run when the model is first loaded , you would use this typescript command:

ProactivelyEvaluate do_init:32

To configure an index to proactively compute its index value at model load time, use:

ProactivelyEvaluate myIndex:1

To configure a variable to compute both its mid-value and its sample value (the uncertainty value) at load time:

ProactivelyEvaluate myVariable:12

Controlling for an entire object class

You can control the default behavior for object classes like Decision, Variable, Index, Objective, Constraint, and Constant. For example, you could make all constants proactive by typing

ProactivelyEvaluate Constant: 5

Turning off the Proactively evaluate indexes preference is equivalent to typing

ProactivelyEvaluate Index: 0

And turning it on is equivalent to setting it to 1.

You can look at the current defaults from the Typescript Window, e.g.

Untitled> Profile Index
Object Index
NodeColor: 39321,39325,65535
ProactivelyEvaluate: 0

You can override this default for individual variable objects by setting the attribute explicitly for the indicated variable. For example:

Untitled> ProactivelyEvaluate Va1: 4
Untitled> ProactivelyEvaluate In1: 0

The above lines change the default so that index In1 is lazily evaluated and variable Va1 is proactively evaluated, regardless of the class default.

Proactively submitting changes to a table

When the 16 flag is set for an edit table, it accepts any change to a cell immediately. This is equivalent to the user pressing the green check button immediately after entering each cell. In a MultiTable, this can be useful to trigger any computed cells to recalculate mmediately so that they are consistent with user changes. It also forces any OnChange event to trigger after each cell change. Of course, this might be undesirable for very large table since it may cause a delay after each change -- and you can no longer drop all changes by pressing the red X button, since the changes have already been committed.

When Proactive Evaluation occurs

When you configure a variable X for proactive evaluation, it occurs: (a) when the model is first loaded, and (b) when the definition of X is changed (e.g., by editing it in the object window). In a future release, we plan to add (c) when any value it depends on changes.

Suppose you change the definition of a variable that influences X. This does not cause the immediate proactive evaluation of X. Thus, if you have an output control for X, it will switch to a Calc button. If the definition of X is edited, then it will proactively evaluate.

History

Analytica adopted lazy evaluation as part of its original design philosophy. The main exception was for Indexes, which it evaluated proactively so that they would be available for display of result tables and graphs using those indexes. In more recent releases, it has moved to lazy evaluation even for indexes where possible, and given the modeler the option of proactive evaluation for selected variables.

In Analytica 4.3 and earlier releases, it tried to evaluate every Index on loading the model. You can still set this behavior by checking the Proactively evaluate indexes preference setting. But it's almost always best to turn this setting off, so you don't have to wait for computed indexes (which may include time-consuming database queries) to evaluate when you are loading your model.  Prior to Analytica 4.4, this setting was on by default, so if you are working with a legacy model, you may need to turn it off.

Analytica 4.3 introduced the ProactivelyEvaluate attribute to let you turn off proactive evaluation of all index nodes, and turn on proactive evaluation for other class types or individual objects. Its default was still to proactively evaluate indexes.

Analytica 4.4 exposed the Proactively evaluate indexes preference on the Preference Dialog, and set the default to off for new models. For legacy models, it remained on to avoid breaking backward compatibility. But users were recommended to turn it off.

A variable used as a table index (even if it isn't formally an index) was evaluated proactively at model load time to enable the table definition to be parsed, up through Analytica 4.3. An internal restructuring of table parsing rendered Analytica 4.4 made this unnecessary, so that even indexes used by tables are evaluated in a lazy fashion.

Analytica 5.0 Introduced proactive acceptance of definitions (flag 16) and proactive evaluation of OnClick (flag 32).

Analytica 6.0 added proactive calculation of output nodes, and the "Configure Proactive User Outputs" library.

See Also

Comments


You are not allowed to post comments.