Difference between revisions of "ComputedBy"

 
 
(12 intermediate revisions by 4 users not shown)
Line 1: Line 1:
= ComputedBy(X) =
+
[[category:Evaluation Functions]]
 +
[[category:Top level functions]]
  
Used to indicate that the value of a variable is computed as a side-effect of a different variable X.
+
== ComputedBy(X'', initial'') ==
  
When a variable, A, has the definition
+
Used to indicate that the value of a variable is computed as a [[side effects|side effect]] of a different variable «X».
ComputedBy(X)
 
  
Then the definition of X must contain an assignment statement, ''A := value'', that sets the value of A.
+
When a variable '''A''', has the definition <code>ComputedBy(X)</code>, then the definition of «X» must contain an assignment statement, <code>A := value</code>, that sets the value of '''A'''.
  
= Referential Transparency =
+
[[ComputedBy]] can only appear at the top level of a Variable's definition.
  
Analytica's modeling language is [http://en.wikipedia.org/wiki/Referential_transparency referentially transparent], so that side-effects in general are not allowed.  However, in some cases it is natural to set another variable as a side-effect of a computation.  ComputedBy makes this possible without a loss of referential transparency.
+
The optional parameter «initial» holds a scalar value (usually a text value) that serves as the initial value if «X» reads its value before setting it, and can also updates when «X» changes its value.
  
= When to Use =
+
== Examples ==
 +
[[ComputedBy]] is particularly convenient within an [[Iterate]] function, when you want to update multiple quantities for each iteration.  For example:
  
ComputedBy can be particularly convenient within an [[Iterate]] function, when multiple quantities need to be updated at each iteration.  Prior to the introduction of ComputedBy, it was necessary to bundle all quantites together, using [[Using References|references]], and then unbundle them.  With computed by, this can be accomplished as follows:
+
:<code>Variable A ::= ComputedBy(The_iteration)</code>
 +
:<code>Variable B ::= ComputedBy(The_iteration)</code>
 +
:<code>Variable The_iteration ::= Iterate(initial: (A := A0; B := B0),</code>
 +
::<code>expr:(A := F(A, B); B := G(A, B)),</code>
 +
::<code>until: H(A, B),</code>
 +
::<code>maxIter: 100)</code>
  
Variable A := ComputedBy(The_iteration)
+
In other cases, when computing one variable, it is convenient to compute another in the same calculation, for example:
Variable B := ComputedBy(The_iteration)
 
  
Variable The_iteration := Iterate( initial:(A:=A0;B:=B0),
+
:<code>Variable Component_Variance ::= ComputedBy(Principle_Components)</code>
                                    expr:(A:=F(A,B);B:=G(A,B)),
+
:<code>Variable Principle_Components ::=</code>
                                    until: H(A,B),
+
::<code>[[Local]] (eigValue, eigVector) := [[EigenDecomp]](X, I, J);</code>
                                    maxIter:100 )
+
::<code>Component_Variance := eigValue;</code>
 +
::<code>eigVector</code>
  
In other cases, there are times in which a useful quantity is computed in the course of computing a primary quantity.  The secondary quantity can be stored in a variable defined as ComputedBy. The following is an example:
+
Note: The above definition of <code>Principle_components</code> can be shortened using a "trick":
 +
:<code>Variable Principle_Components ::=</code>
 +
::<code>( , ComponentVariance ) := [[EigenDecomp]](X, I, J)</code>
 +
Here the first return value (the eigen value) is passed throw whereas the second return value (the eigen vector) is assigned to <code>Component_Variance</code>.
  
Variable Component_Variance := ComputedBy( Principle_Components )
+
The next example uses an «initial» value to hold a default filename, such that if the user ends up selecting a different file name, it saves the new value.
  
Variable Principle_Components :=  
+
:Variable MyDataFilename ::= <code>[[ComputedBy]]( MyData, "MyData.csv" )</code>
      Var eig := EigenDecompose(X,I,J);
+
:Variable MyData ::= <code>( , MyDataFilename ) := [[ReadTextFile]]( MyDataFilename )</code>
      Component_Variance := eig[.item='value'];
 
      #eig[.item='vector']
 
  
= Use in [[Dynamic]] =
+
In the above, note that [[ReadTextFile]] has two return values, the content of the file, and the actual filename read. The left-hand side of the assignment in <code>MyData</code> assigns the second return value to <code>MyDataFilename</code>, without assigning the first value to anything. Since the first return value is the result of the assignment operator, the final result for <code>MyData</code> is the content of the file. If the file <code>"MyData.csv"</code> exists, then the file is read with no user intervention. However, if it is not found, the user sees a file selector dialog. Suppose the user selects the file <code>"TodaysData.csv"</code>. After evaluation of <code>MyData</code> completes, the definition of <code>MyDataFilename</code> is now:
 +
:<code>[[ComputedBy]]( MyData, "TodaysData.csv" )</code>
 +
If <code>MyData</code> is re-evaluated in the future, perhaps after saving and reloading the model, it will attempt to open <code>"TodaysData.csv"</code>.
  
When A := ComputedBy(X), and X is within a [[Dynamic]] loop, then the assignment within X sets the value of A for the current [[Time]]Thus, A will also be indexed by [[Time]] when the computation completes.
+
==More details==
 +
=== Referential Transparency ===
 +
Analytica's modeling language is [http://en.wikipedia.org/wiki/Referential_transparency referentially transparent], so that side-effects in general are not allowed.  However, in some cases it is natural to set another variable as a side-effect of a computation.  [[ComputedBy]] makes this possible without a loss of referential transparency.
  
= Evaluation Mode =
+
=== Use in Dynamic ===
  
When A := ComputedBy(X), if the assignment to A inside of X's definition occurs from within a [[Sample]] evaluation context, then the [[Evaluation Modes|Sample]] value of A is set.  Likewise, if the assignment occurs from a [[Mid]] context, then the [[Evaluation Modes|Mid]] value of A is set.
+
When <code>A := ComputedBy(X)</code>, and «X» is within a [[Dynamic]] loop, then the assignment within «X» sets the value of '''A''' for the current [[Time]].  Thus, '''A''' will also be indexed by [[Time]] when the computation completes.
  
= Availability =
+
=== Evaluation Mode ===
 
+
When <code>A := ComputedBy(X)</code>, if the assignment to '''A''' inside of «X»'s definition occurs from within a [[Sample]] evaluation context, then the [[Evaluation Modes|Sample]] value of '''A''' is setLikewise, if the assignment occurs from a [[Mid]] context, then the [[Evaluation Modes|Mid]] value of '''A''' is set.
ComputedBy is not officially supported as of release 4.0.0, although it is present in the buildIt is currently considered an experimental feature, and is not documented in the User's Guide.
 
 
 
= See Also =
 
  
 +
== See Also ==
 +
* [[Side effects]]
 
* [[Iterate]]
 
* [[Iterate]]
 
* [[Dynamic]]
 
* [[Dynamic]]
 
* [[Using References]]
 
* [[Using References]]

Latest revision as of 19:30, 8 January 2025


ComputedBy(X, initial)

Used to indicate that the value of a variable is computed as a side effect of a different variable «X».

When a variable A, has the definition ComputedBy(X), then the definition of «X» must contain an assignment statement, A := value, that sets the value of A.

ComputedBy can only appear at the top level of a Variable's definition.

The optional parameter «initial» holds a scalar value (usually a text value) that serves as the initial value if «X» reads its value before setting it, and can also updates when «X» changes its value.

Examples

ComputedBy is particularly convenient within an Iterate function, when you want to update multiple quantities for each iteration. For example:

Variable A ::= ComputedBy(The_iteration)
Variable B ::= ComputedBy(The_iteration)
Variable The_iteration ::= Iterate(initial: (A := A0; B := B0),
expr:(A := F(A, B); B := G(A, B)),
until: H(A, B),
maxIter: 100)

In other cases, when computing one variable, it is convenient to compute another in the same calculation, for example:

Variable Component_Variance ::= ComputedBy(Principle_Components)
Variable Principle_Components ::=
Local (eigValue, eigVector) := EigenDecomp(X, I, J);
Component_Variance := eigValue;
eigVector

Note: The above definition of Principle_components can be shortened using a "trick":

Variable Principle_Components ::=
( , ComponentVariance ) := EigenDecomp(X, I, J)

Here the first return value (the eigen value) is passed throw whereas the second return value (the eigen vector) is assigned to Component_Variance.

The next example uses an «initial» value to hold a default filename, such that if the user ends up selecting a different file name, it saves the new value.

Variable MyDataFilename ::= ComputedBy( MyData, "MyData.csv" )
Variable MyData ::= ( , MyDataFilename ) := ReadTextFile( MyDataFilename )

In the above, note that ReadTextFile has two return values, the content of the file, and the actual filename read. The left-hand side of the assignment in MyData assigns the second return value to MyDataFilename, without assigning the first value to anything. Since the first return value is the result of the assignment operator, the final result for MyData is the content of the file. If the file "MyData.csv" exists, then the file is read with no user intervention. However, if it is not found, the user sees a file selector dialog. Suppose the user selects the file "TodaysData.csv". After evaluation of MyData completes, the definition of MyDataFilename is now:

ComputedBy( MyData, "TodaysData.csv" )

If MyData is re-evaluated in the future, perhaps after saving and reloading the model, it will attempt to open "TodaysData.csv".

More details

Referential Transparency

Analytica's modeling language is referentially transparent, so that side-effects in general are not allowed. However, in some cases it is natural to set another variable as a side-effect of a computation. ComputedBy makes this possible without a loss of referential transparency.

Use in Dynamic

When A := ComputedBy(X), and «X» is within a Dynamic loop, then the assignment within «X» sets the value of A for the current Time. Thus, A will also be indexed by Time when the computation completes.

Evaluation Mode

When A := ComputedBy(X), if the assignment to A inside of «X»'s definition occurs from within a Sample evaluation context, then the Sample value of A is set. Likewise, if the assignment occurs from a Mid context, then the Mid value of A is set.

See Also

Comments


You are not allowed to post comments.