Difference between revisions of "Evaluate"

Line 4: Line 4:
 
== Evaluate(t) ==
 
== Evaluate(t) ==
  
[[Evaluate]] expects a text value «t», and evaluates it as though it were an expression in a definition. It returns the value resulting from evaluating the expression. For example:
+
[[Evaluate]] expects a [[Text values|text value]] «t», and evaluates it as though it were an [[expression]] in a [[definition]]. It returns the [[value]] resulting from evaluating the expression. For example:
  
 
:<code>Evaluate('10M /10') &rarr; 1M</code>
 
:<code>Evaluate('10M /10') &rarr; 1M</code>
Line 14: Line 14:
 
:<code>Evaluate('100M') &rarr; 100M</code>
 
:<code>Evaluate('100M') &rarr; 100M</code>
  
Like most other functions, it returns the deterministic ([[Mid]]) or probabilistic value, according to the context in which it is called. [[Evaluate]] is powerful, and useful for a variety of purposes, but, it has some subtle aspects. Consider:
+
Like most other [[functions]], it returns the deterministic ([[Mid]]) or probabilistic value, according to the context in which it is called. [[Evaluate]] is powerful, and useful for a variety of purposes, but, it has some subtle aspects. Consider:
  
 
:<code>Variable A := 99</code>
 
:<code>Variable A := 99</code>
Line 22: Line 22:
 
The Variable <code>A</code> in the evaluated text <code>'A + 1'</code> refers to the global <code>A</code>, not the local <code>A</code> defined in <code>B</code>. More generally:
 
The Variable <code>A</code> in the evaluated text <code>'A + 1'</code> refers to the global <code>A</code>, not the local <code>A</code> defined in <code>B</code>. More generally:
  
* [[Evaluate]](t) creates its own context for parsing «t» (at evaluation time), which is quite separate from the context of the expression in which the [[Evaluate]](t) appears.e.g., the definition of <code>B</code> above.
+
* [[Evaluate]](t) creates its own context for [[Parsed Expressions|parsing]] «t» (at evaluation time), which is quite separate from the context of the expression in which the [[Evaluate]](t) appears.e.g., the definition of <code>B</code> above.
* So, text «t» cannot refer to local Variables, indexes, or function parameters defined in the context in which the [[Evaluate]](t) function appears.
+
* So, text «t» cannot refer to [[local variable]]s, [[index]]es, or [[function parameters]] defined in the context in which the [[Evaluate]](t) function appears.
* If the text value of «t» refers to any global Variables—e.g., <code>A</code> in the definition of <code>B</code> above—these will not appear as Inputs of <code>B</code>, nor will any changes to <code>A</code> cause automatic re-evaluation of <code>B</code>.
+
* If the text value of «t» refers to any global variables—e.g., <code>A</code> in the definition of <code>B</code> above—these will not appear as Inputs of <code>B</code>, nor will any changes to <code>A</code> cause automatic re-evaluation of <code>B</code>.
 
* Text «t» may itself define local Variables and indexes, and refer to them, but these will not be available outside «t».
 
* Text «t» may itself define local Variables and indexes, and refer to them, but these will not be available outside «t».
 
* When [[Evaluate]] references another variable, Analytica will not be able to track the dependency. For example:
 
* When [[Evaluate]] references another variable, Analytica will not be able to track the dependency. For example:
Line 60: Line 60:
 
:<code>Evaluate(TheVar) &rarr; 5  { evaluates A }</code>
 
:<code>Evaluate(TheVar) &rarr; 5  { evaluates A }</code>
  
It is worth nothing that an alternative method also exists for evaluating a [[varTerm]].  If you assign an existing [[varTerm]] (handle to an object) to a local variable, that variable becomes an alias for the object identifier.  If that local variable then appears in a value context, this also returns the value of the target variable:
+
It is worth nothing that an alternative method also exists for evaluating a [[varTerm]].  If you assign an existing [[varTerm]] ([[handle]] to an object) to a [[local variable]], that variable becomes an [[alias]] for the object [[identifier]].  If that local variable then appears in a value context, this also returns the value of the target variable:
  
 
:<code>Var x := TheVar Do x &rarr; 5    { x is an alias for A, so "x" in the body is the value of A }</code>
 
:<code>Var x := TheVar Do x &rarr; 5    { x is an alias for A, so "x" in the body is the value of A }</code>
Line 80: Line 80:
 
Parameters to the function being called are always passed by position, i.e., you cannot use a named-parameter calling syntax as you might if you were calling the function directly.   
 
Parameters to the function being called are always passed by position, i.e., you cannot use a named-parameter calling syntax as you might if you were calling the function directly.   
  
If the function being called contains repeated (or variable number of) parameters, and you need to include a parameter that follows the repeated parameter, then you must place brackets around the repeated parameters.  For example,  
+
If the function being called contains repeated (or variable number of) parameters, and you need to include a parameter that follows the [[repeated parameter]], then you must place brackets around the repeated parameters.  For example,  
  
 
:<code> Function Fu1(x; y: repeated; z: optional) := ...</code>
 
:<code> Function Fu1(x; y: repeated; z: optional) := ...</code>
Line 94: Line 94:
 
::''Equivalent to <code>F(1, 2, 3, 4)''</code>
 
::''Equivalent to <code>F(1, 2, 3, 4)''</code>
  
Several common built-in functions, including [[Sum]], [[Max]], and [[Min]], allow a variable number of indexes, so that you can use <code>Sum(A, I, J, K)</code> to sum over 3 dimensions in a single call.  These functions also have optional parameters, such as «ignoreNonNumbers», so that if you need to specify these optional parameters, you will need to place brackets around the index(es), even if only one (or zero) index is specified.  For example, the following examples show how to to specify «ignoreNonNumbers» as true to [[Sum]], when summing over a single index, and when summing over the implicit dimension:
+
Several common built-in functions, including [[Sum]], [[Max]], and [[Min]], allow a variable number of indexes, so that you can use <code>Sum(A, I, J, K)</code> to sum over 3 dimensions in a single call.  These functions also have [[optional parameter]]s, such as «ignoreNonNumbers», so that if you need to specify these optional parameters, you will need to place brackets around the index(es), even if only one (or zero) index is specified.  For example, the following examples show how to to specify «ignoreNonNumbers» as true to [[Sum]], when summing over a single index, and when summing over the [[implicit dimension]]:
  
 
:<code>Evaluate(Handle(Sum), A, [I], true)</code>
 
:<code>Evaluate(Handle(Sum), A, [I], true)</code>
Line 111: Line 111:
 
* [[Expression Syntax]]
 
* [[Expression Syntax]]
 
* [[Expression Assist]]
 
* [[Expression Assist]]
 +
* [[Parsed Expressions]]
 
* [[Function calls and parameters]]
 
* [[Function calls and parameters]]
 
* [[Summary of Programming Constructs]]
 
* [[Summary of Programming Constructs]]
 
* [[Procedural Programming]]
 
* [[Procedural Programming]]

Revision as of 19:21, 22 August 2016


Evaluate(t)

Evaluate expects a text value «t», and evaluates it as though it were an expression in a definition. It returns the value resulting from evaluating the expression. For example:

Evaluate('10M /10') → 1M

If «t» contains any syntax errors, Evaluate returns Null; it will not flag a syntax error.

One use for Evaluate is to convert (coerce) a text representation of a number into the number itself, for example:

Evaluate('100M') → 100M

Like most other functions, it returns the deterministic (Mid) or probabilistic value, according to the context in which it is called. Evaluate is powerful, and useful for a variety of purposes, but, it has some subtle aspects. Consider:

Variable A := 99
Variable B := (VAR A := 0; Evaluate('A + 1'))
B → 100

The Variable A in the evaluated text 'A + 1' refers to the global A, not the local A defined in B. More generally:

  • Evaluate(t) creates its own context for parsing «t» (at evaluation time), which is quite separate from the context of the expression in which the Evaluate(t) appears.e.g., the definition of B above.
  • So, text «t» cannot refer to local variables, indexes, or function parameters defined in the context in which the Evaluate(t) function appears.
  • If the text value of «t» refers to any global variables—e.g., A in the definition of B above—these will not appear as Inputs of B, nor will any changes to A cause automatic re-evaluation of B.
  • Text «t» may itself define local Variables and indexes, and refer to them, but these will not be available outside «t».
  • When Evaluate references another variable, Analytica will not be able to track the dependency. For example:
B := A + 1
C := Evaluate('A + 1')

When A changes, Analytica will automatically ensure that B is updated, but it has no way of knowing C should also be recomputed.

Text «t» may itself be an expression that creates a text value to be evaluated by Evaluate. This text expression appears in the definition of V and is not subject to the above limitations, so, for example:

Variable V :=(Var x:= ’10’; Evaluate(x & x))
V → 1010

When to Use

The cases in which you should use Evaluate are rare. You should be very reluctant to use it due to the caveats listed in the previous section.

Legitimate cases that do occasionally occur:

  • Parsing numbers or simple expressions.
  • (advanced) Use in Meta-Inference algorithms where you are manipulating handles to objects in your model.
  • (rare) Cases where you really do wish to by-pass dependency maintenance. You want it to compute something the first time the result is requested after the model is first loaded, but not update when parent values are changes.

Non-text Parameters

A non-text value can also be passed to Evaluate, which can be of use in some Meta-Inference applications. You need to keep in mind that the parameter to evaluate is evaluated BEFORE the function itself gets it, so evaluating a non-text value is only meaningful when the evaluated parameter is itself something that can still be evaluated. One instance of this that is often useful is the case of a varTerm, i.e., a handle to an object.

For example, suppose

Variable A := 2 + 3
Variable TheVar := VarTerm(A)

In the more general case, you might have a Meta-Inference algorithm that identifies a single variable object through some computation. Having identified the object, TheVar now holds a handle to the object. You then may want to access values or properties of the object pointed to by TheVar, rather than just values or properties of TheVar itself. Evaluate serves this purpose:

TheVar → A { A -- i.e., a handle to the object A }
Evaluate(TheVar) → 5 { evaluates A }

It is worth nothing that an alternative method also exists for evaluating a varTerm. If you assign an existing varTerm (handle to an object) to a local variable, that variable becomes an alias for the object identifier. If that local variable then appears in a value context, this also returns the value of the target variable:

Var x := TheVar Do x → 5 { x is an alias for A, so "x" in the body is the value of A }

When accessing attributes of an object in a Meta-Inference algorithm, where your algorithm has a handle to an object (again, say it is in TheVar), you can access the attribute using e.g.,

Description Of Evaluate(TheVar) → "Description of A"
Description Of TheVar → "Description of TheVar"

(the result of using TheVar alone is shown for comparison).

Invoking Functions

Given a handle to a function object, you can use Evaluate to call the function. If the function expects N parameters, you would provide N+1 parameters to Evaluate -- the first parameter being the handle to the function, and the remaining parameters being the values passed to the function. Example:

MetaVar fn := If opt = 1 then Handle(Max) else if opt = 2 then Handle(Min) else Handle(Sum);
Evaluate(fn, A, I)

Parameters to the function being called are always passed by position, i.e., you cannot use a named-parameter calling syntax as you might if you were calling the function directly.

If the function being called contains repeated (or variable number of) parameters, and you need to include a parameter that follows the repeated parameter, then you must place brackets around the repeated parameters. For example,

Function Fu1(x; y: repeated; z: optional) := ...
 
Evaluate(fn, 1, 2, 3, 4) →
Equivalent to Fu1(1, 2, 3, 4), where [2, 3, 4] are values for y and z is omitted
Evaluate(fn, 1, [2, 3], 4) →
Equivalent to Fu1(1, 2, 3, y: 4), where [2, 3] are values for y, and z is 4.

However, there is a limitation that the first supplied parameter (i.e., the second parameter to Evaluate) cannot be placed inside brackets. Likewise, you cannot pass an literal list by specifying the first parameter as a bracketed list. This is because the repeated-parameter syntax applies equally to Evaluate. If you specify the first parameter to Evaluate in brackets, those become the parameters to the function, i.e.,:

Evaluate(Handle(F), [1, 2, 3, 4]) →
Equivalent to F(1, 2, 3, 4)

Several common built-in functions, including Sum, Max, and Min, allow a variable number of indexes, so that you can use Sum(A, I, J, K) to sum over 3 dimensions in a single call. These functions also have optional parameters, such as «ignoreNonNumbers», so that if you need to specify these optional parameters, you will need to place brackets around the index(es), even if only one (or zero) index is specified. For example, the following examples show how to to specify «ignoreNonNumbers» as true to Sum, when summing over a single index, and when summing over the implicit dimension:

Evaluate(Handle(Sum), A, [I], true)
Var x := [3, 2, 'a', 'b', 6] do Evaluate(Handle(Sum), x, [], true)

Notice that if you don't need to specify the optional «ignoreNonNumbers» parameter (or any parameters that follow the repeated index parameters), then it is more natural to omit the brackets:

Evaluate(Handle(Sum), A, I)
Var x := [3, 2, 5, 3, 6] do Evaluate(Handle(Sum), x)

See Also

Comments


You are not allowed to post comments.