Difference between revisions of "Proactive Evaluation"

Line 11: Line 11:
 
:[[image:proactive preference.png]]
 
:[[image:proactive preference.png]]
  
== Custom configuration with ''ProactivelyEvaluate'' attribute ==
+
== Proactively compute user outputs ==
  
Occasionally, it is useful to turn on proactive evaluation for selected variables. One case is when you want to show a result in a user Output node immediately when you display the Diagram user interface that contains it, without having to click its '''Calc''' button.  In addition, Proactive evaluation causes variables with output nodes showing to reevaluate immediately if anything they depend on is changed, which is useful when an output node appears on a user interface so that the value is updated without having to press a '''Calc''' button each time.  This capability requires [[Analytica 5.5]] or later.
+
''New to [[Analytica 5.5]]''
  
Another case would be if you wanted to display a [[MsgBox|message box]] with welcome information when a model is loaded. You could call the MsgBox() function in a proactively evaluated variable or button.
+
When you have created a model UI for your user with input and output nodes, the output nodes will display a '''[calc]''' button initially. You press the '''[calc]''' button to launch the calculation. When you configure your outputs to proactively calculate, the calculation launches as soon as the diagram is shown, without having to press the '''[calc]''' button.  When you change upstream inputs, the proactive outputs automatically recompute.  
  
You cause proactive evaluation at model load time for an index by setting its ProactivelyEvaluate attribute to <code>1</code>. You can set it back to <code>0</code> for lazy evaluationYou can also change the default behavior for an entire class of Objects by setting ProactivelyEvaluate attribute for a [[Class]] -- e.g. for Index.  
+
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 resultHence, you should really only use proactive evaluation for calculations that complete very quickly -- like no more than a few seconds.
  
Since ProactivelyEvaluate attribute is rather obscure, you must set it in the [[Typescript Window]], which you can get to by pressing ''F12'' (or ''Ctrl-''').  
+
You can specify that output variables should proactively compute at three levels:
 +
* Module level:  The setting applies to all user outputs on the diagram.
 +
* Variable level: The setting applies to all user outputs for the variable, which may appear on different diagrams.  Also, this will cause the variable to be proactively computed when the model is first loaded.
 +
* Output node level: The setting applies to a single 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 also have the options to
 +
* Proactively compute outputs only in browse mode, or proactively compute in both browse and edit mode.
 +
*:Because UIs are meant to be used in browse mode, it is nice to keep proactive calculation off in edit mode while you are developing your model logic.
 +
* Proactively compute only mid-value, only uncertain-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 ===
 +
To configure the proactive evaluation for your model's UI, first use '''Add Library...''' on the [[File menu]] to embed the <code>"Configure Proactive User Outputs"</code> library in your model. Then enter the library, where you'll find this panel:
 +
 +
<center>[[image:Configure proactive configuration.png]]</center>
 +
 +
If you've added modules or user outputs since you last visited this panel, press the '''[Refresh]''' button. Then select the diagram containing your user interface from the "Which diagram" dropdown.  Only modules with user output nodes appear as options.
 +
 +
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, a third pulldown appears that allows you to select which variable or output to set. If an output is set to proactively compute at any of these three levels, then it computes.
 +
 +
=== Errors during proactive calculations ===
 +
If an error or warning is encountered during a proactive calculation, it quietly aborts and the '''[calc]''' button appears. When you press the '''[calc]''' button you'll see the error. Once an error has been detected, it avoids re-attempting the calculation again until something upstream that it depends on changes. This is because until something has changed, it is expected to re-encounter the same error every time it tries. 
 +
 +
== Proactively calculating when a model is first loaded ==
 +
You can configure indexes, variables or buttons to compute (or click) when your model first loads. These events occur after the model is read into memory and parsed, but while the loading progress dialog is still on the screen.
 +
 +
One example use case would be if you wanted to display a [[MsgBox|message box]] with welcome information when a model is loaded. You could call the MsgBox() function in a proactively evaluated variable or button.  Or you could use an [[AskMsgText]] dialog to ask for user name or password.  You could schedule a calculation at load time so results are precomputed once the model is fully loaded. In most cases, that is undesirable, since you pay the cost of waiting for the calculation every time you load the model, but you may feel it is better to pay that at load time to obtain a snappy first interaction one the user starts using the model.
 +
 +
To configure these, you need to set the '''ProactivelyEvaluate''' attribute.  Since '''ProactivelyEvaluate''' attribute is rather obscure, you must set it in the [[Typescript Window]], which you can get to by pressing ''F12'' (or ''Ctrl-'''). 
 +
 +
The value assigned to the '''ProactivelyEvaluate''' attribute is a bit-field, which can be the sum of any of the following values:
 +
:<code>1</code> = Index Value
 +
:<code>2</code> = Domain value
 +
:<code>4</code> = Mid value
 +
:<code>8</code> = Prob value
 +
:<code>16</code> = Accept definition
 +
:<code>32</code> = OnClick
 +
:<code>64</code> = Proactively evaluate output node in edit mode. (If unset, then only happens in browse mode)
 +
 +
To configure a button with the identifier <code>do_init</code> to run when the model is first loaded , you would use this typescript command:
 +
:<code>ProactivelyEvaluate do_init:32</code>
 +
 +
To configure an index to proactively compute its index value at model load time, use:
 +
:<code>ProactivelyEvaluate myIndex:1</code>
 +
 +
To configure a variable to compute both its mid-value and its sample value (the uncertainty value) at load time:
 +
:<code>ProactiveEvaluate myVariable:12</code>
 +
 +
=== 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
 
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
 
:<code>ProactivelyEvaluate Constant: 5</code>
 
:<code>ProactivelyEvaluate Constant: 5</code>
Line 41: Line 87:
 
The above lines change the default so that index <code>In1</code> is lazily evaluated and variable <code>Va1</code> is proactively evaluated, regardless of the class default.
 
The above lines change the default so that index <code>In1</code> is lazily evaluated and variable <code>Va1</code> is proactively evaluated, regardless of the class default.
  
The value assigned to the ''ProactivelyEvaluate'' attribute is actually a bit-field, which can be the sum of any of the following values:
+
== Proactively submitting changes to a table ==
 
 
:<code>1</code> = Index Value
 
:<code>2</code> = Domain value
 
:<code>4</code> = Mid value
 
:<code>8</code> = Prob value
 
:<code>16</code> = Accept definition
 
:<code>32</code> = OnClick
 
:<code>64</code> = Proactively evaluate output node in edit mode. (If unset, then only happens in browse mode)
 
 
 
Setting to <code>1</code>, as the previous examples do, cause Analytica to compute the index value.  In many cases, computing the index value (or discovering that there is no [[self]]-index value) will also require evaluate of the [[Mid]] value.  Alternatively, setting it to <code>4</code> would force the proactive computation of the mid-value.
 
 
 
 
(''new to [[Analytica 5.0]]'') When the <code>16</code> flag is set for an edit table, the table's definition is entered immediately when a cell is changed. This is equivalent to the user pressing the green check button immediately after entering each cell. In a [[MultiTable]], this can be useful for triggering the recomputation of computed cells immediately. In any table, it can also be used to force the [[OnChange]] event to trigger after every cell change. Of course, for extremely large table, it may be undesirable to set this flag since large time delays might result, and it means you can't drop all changes by pressing the red X button, since the changes have already been committed.
 
(''new to [[Analytica 5.0]]'') When the <code>16</code> flag is set for an edit table, the table's definition is entered immediately when a cell is changed. This is equivalent to the user pressing the green check button immediately after entering each cell. In a [[MultiTable]], this can be useful for triggering the recomputation of computed cells immediately. In any table, it can also be used to force the [[OnChange]] event to trigger after every cell change. Of course, for extremely large table, it may be undesirable to set this flag since large time delays might result, and it means you can't drop all changes by pressing the red X button, since the changes have already been committed.
  

Revision as of 00:21, 16 October 2020


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 to view its result, or you ask for the result of 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 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, and

In cases where a diagram contains a Choice pulldown menu input control or an edit table, Analytica will pro-actively evaluate any index used in the menu or edit table so that it can display them properly. 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.

Proactive preference.png

Proactively compute user outputs

New to Analytica 5.5

When you have created a model UI for your user with input and output nodes, the output nodes will display a [calc] button initially. You press the [calc] button to launch the calculation. When you configure your outputs to proactively calculate, the calculation launches as soon as the diagram is shown, without having to press the [calc] button. When you change upstream inputs, the proactive outputs automatically recompute.

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. Hence, you should really only use proactive evaluation for calculations that complete very quickly -- like no more than a few seconds.

You can specify that output variables should proactively compute at three levels:

  • Module level: The setting applies to all user outputs on the diagram.
  • Variable level: The setting applies to all user outputs for the variable, which may appear on different diagrams. Also, this will cause the variable to be proactively computed when the model is first loaded.
  • Output node level: The setting applies to a single 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 also have the options to

  • Proactively compute outputs only in browse mode, or proactively compute in both browse and edit mode.
    Because UIs are meant to be used in browse mode, it is nice to keep proactive calculation off in edit mode while you are developing your model logic.
  • Proactively compute only mid-value, only uncertain-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

To configure the proactive evaluation for your model's UI, first use Add Library... on the File menu to embed the "Configure Proactive User Outputs" library in your model. Then enter the library, where you'll find this panel:

Configure proactive configuration.png

If you've added modules or user outputs since you last visited this panel, press the [Refresh] button. Then select the diagram containing your user interface from the "Which diagram" dropdown. Only modules with user output nodes appear as options.

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, a third pulldown appears that allows you to select which variable or output to set. If an output is set to proactively compute at any of these three levels, then it computes.

Errors during proactive calculations

If an error or warning is encountered during a proactive calculation, it quietly aborts and the [calc] button appears. When you press the [calc] button you'll see the error. Once an error has been detected, it avoids re-attempting the calculation again until something upstream that it depends on changes. This is because until something has changed, it is expected to re-encounter the same error every time it tries.

Proactively calculating when a model is first loaded

You can configure indexes, variables or buttons to compute (or click) when your model first loads. These events occur after the model is read into memory and parsed, but while the loading progress dialog is still on the screen.

One example use case would be if you wanted 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. Or you could use an AskMsgText dialog to ask for user name or password. You could schedule a calculation at load time so results are precomputed once the model is fully loaded. In most cases, that is undesirable, since you pay the cost of waiting for the calculation every time you load the model, but you may feel it is better to pay that at load time to obtain a snappy first interaction one the user starts using the model.

To configure these, you need to set the ProactivelyEvaluate' attribute. Since ProactivelyEvaluate attribute is rather obscure, you must set it in the Typescript Window, which you can get to by pressing F12 (or Ctrl-).

The value assigned to the ProactivelyEvaluate attribute is a bit-field, which can be the sum of any of the following values:

1 = Index Value
2 = Domain value
4 = Mid value
8 = Prob value
16 = Accept definition
32 = OnClick
64 = Proactively evaluate output node in edit mode. (If unset, then only happens 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:

ProactiveEvaluate 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

(new to Analytica 5.0) When the 16 flag is set for an edit table, the table's definition is entered immediately when a cell is changed. This is equivalent to the user pressing the green check button immediately after entering each cell. In a MultiTable, this can be useful for triggering the recomputation of computed cells immediately. In any table, it can also be used to force the OnChange event to trigger after every cell change. Of course, for extremely large table, it may be undesirable to set this flag since large time delays might result, and it means you can't drop all changes by pressing the red X button, since the changes have already been committed.

(new to Analytica 5.0) The 32 flag applies to buttons or images having an OnClick event handler, and indicate that the button's OnClick should be evaluated immediately when the model is loaded.

When Proactive Evaluation occurs

When a variable X is configured to be proactively evaluated, this proactive evaluation 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.

(As of Analytica 4.5) Suppose the definition of a variable that X depends on changes. 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. (Enhancement being considered: A variable set to proactively evaluate Mid = 4 or Prob = 8 would automatically evaluate when the output control is rendered on the diagram. The Calc button would appear only when the evaluation is unsuccessful because of an error or user abort).

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.

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).

See Also

Comments


You are not allowed to post comments.