Difference between revisions of "While..Do"

 
(6 intermediate revisions by one other user not shown)
Line 2: Line 2:
 
[[Category:Doc Status D]] <!-- For Lumina use, do not change -->
 
[[Category:Doc Status D]] <!-- For Lumina use, do not change -->
 
   
 
   
= While (''test'') Do ''body'' =
+
== While (''test'') Do ''body'' ==
 +
'''While''' evaluates «body» repeatedly as long as «test» ''<> 0''.
  
''While'' evaluates ''body'' repeatedly as long as ''test<>0''.  
+
In order for [[While]] to terminate, «body» must produce a side-effect on a local variable that is used by «test», causing «test» eventually to equal 0.  If «test» never becomes ''false'', [[While]] continues to loop indefinitely.  If you suspect that might be happening, type ''Control+Break'' or ''Control+.'' (''Control+period'') to interrupt evaluation.
  
In order for ''While'' to terminate, ''body'' must produce a side-effect on a local variable that is used by ''test'', causing ''test'' eventually to equal 0.  If ''test'' never becomes ''false'', ''While'' continues to loop indefinitely.  If you suspect that might be happening, type ''Control''+Break or ''Control+.'' (''Control''+period'') to interrupt evaluation.
+
[[While]] returns the final value found in the last iteration of «body», or [[Null]] if no iterations occur.
  
''While'' returns the final value found in the last iteration of ''body'', or [[Null]] if no iterations occur.
+
«Test» must evaluate to an atomic (non-array) value; therefore, it is a good idea to force any local variable used in «test» to be atomic valued. [[While]] is one of the few constructs in Analytica that does not generalize completely to handle arrays. But, there are ways to ensure that variables and functions using [[While]] support [[Intelligent Arrays]] and probabilistic evaluation.
  
''Test'' must evaluate to an atomic (non-array) value; therefore, it is a good idea to force any local variable used in ''test'' to be atomic valued. While is one of the few constructs in Analytica that does not generalize completely to handle arrays. But, there are ways to ensure that variables and functions using ''While'' support Intelligent Arrays and probabilistic evaluation.
+
== Examples ==
 +
:<code>Local n := 1;</code>
 +
:<code>While n < 1000 do n := 2*n</code>
 +
:<code> n &rarr; 1024</code>
  
= Examples =
+
:<code>Local x := 1;</code>
 +
:<code>Local prev := 0;</code>
 +
:<code>while Abs(x - prev) > 1e-6 do (</code>
 +
::<code>prev := x ; </code>
 +
::<code>x := 1 + 1/(1 + x)</code>
 +
:<code>)</code>
 +
:<code>x &rarr; 1.414214</code>
  
[[Var]] n := 1;
+
== Array Abstraction with While ==
  While n<1000 do n := 2*n
+
The [[While]] construct is one of a few constructs in Analytica that does not fully [[Array abstraction|array abstract]].  The limitation arises from the fact that «test» must be a scalar value, i.e., it cannot be array valued. Consider, for example, the following expression:
--> ''returns'' 1024
 
  
[[Var]] x := 1;
+
:<code>Local n := start;</code>
[[Var]] prev := 0;
+
:<code>Local steps := 0;</code>
while [[Abs]](x-prev)>1e-6 do (
+
:<code>While n > 1 do (</code>
    prev:=x ;  
+
::<code>n := If Mod(n, 2) = 0 then n/2 else 3*n + 1;</code>
    x:=1 + 1/(1+x)
+
::<code>steps := steps + 1</code>
+
:<code>)</code>
--> ''returns'' 1.414214
 
 
 
= Array Abstraction with While =
 
 
 
The ''While'' construct is one of a few constructs in Analytica that does not fully array abstract.  The limitation arises from the fact that ''test'' must be a scalar value, i.e., it cannot be array valued.  Consider, for example, the following expression:
 
 
 
Var n := start;
 
Var steps := 0;
 
While n>1 do (
 
    n := If Mod(n,2)=0 then n/2 else 3*n+1;
 
    steps := steps + 1
 
)
 
 
   
 
   
If ''start=20'' when this is evaluated, this returns 7 (''n'' steps through values of 20, 10, 5, 16, 8, 4, 2, 1).  If ''start=22'', it returns 15, and for ''start==27'' it returns 111.  One of the key features of an Analytica model is the ability to easily add a dimension to an input without having to change the model's internals. So what we'd like is that when ''start'' is set to the list [20,22,27], the expression would array-abstract and return the result array [7,15,111].  However, the above expression will result in an error, complaining that ''test'' is not a scalar.
+
If <code>start = 20</code> when this is evaluated, this returns <code>7</code> (''n'' steps through values of <code>20, 10, 5, 16, 8, 4, 2, 1</code>).  If <code>start = 22</code>, it returns <code>15</code>, and for <code>start = 27</code> it returns <code>111</code>.  One of the key features of an Analytica model is the ability to easily add a dimension to an input without having to change the model's internals. So what we'd like is that when <code>start</code> is set to the list <code>[20, 22, 27]</code>, the expression would array-abstract and return the result array <code>[7, 15, 111]</code>.  However, the above expression will result in an error, complaining that «test» is not a scalar.
 
 
While disallows ''test'' to be an array, because otherwise the criteria for termination is ambiguous.  It may be that for certain elements, the loop should be terminated, while for others it should not. 
 
 
 
These problems can be addressed by declaring the dimensionality of all parameters that influence the ''test''.  We can do this simply in this example by listing the dimensions of 'n'' when it is declared -- in this case listing zero dimensions, hence there are no index identifiers between the brackets in its declaration:
 
  
  Var n[ ] := start;
+
While disallows «test» to be an array, because otherwise the criteria for termination is ambiguous. It may be that for certain elements, the loop should be terminated, while for others it should not.  
Var steps := 0;
 
While n>1 do (
 
    n := If Mod(n,2)=0 then n/2 else 3*n+1;
 
    steps := steps + 1
 
  )
 
  
When this is evaluated and ''start'' is array-valued, Analytica sees that n must be scalar in the expression that uses ''n''To accomplish that, Analytica will iterate as necessary, setting ''n'' to a single scalar value each time.  Without the brackets, ''n'' is passed down as an array.
+
These problems can be addressed by declaring the dimensionality of all parameters that influence «test»We can do this simply in this example by listing the dimensions of ''n'' when it is declared -- in this case listing zero dimensions, hence there are no index identifiers between the brackets in its declaration:
  
The ''While..Do'' construct is used most often from within [[User-Defined Functions]].  In this case, the dimensionality declaration shoudl be placed on the [[Function Parameter Qualifiers]].  In this case, we would declare the parameter ''start'' to be atomic:
+
:<code>Local n[ ] := start;</code>
 +
:<code>Local steps := 0;</code>
 +
:<code>While n > 1 do (</code>
 +
::<code>n := If Mod(n, 2) = 0 then n/2 else 3*n + 1;</code>
 +
::<code>steps := steps + 1</code>
 +
:<code>)</code>
  
Function Num3nSteps( start : atomic )
+
When this is evaluated and <code>start</code> is array-valued, Analytica sees that ''n'' must be scalar in the expression that uses ''n''.  To accomplish that, Analytica will iterate as necessary, setting ''n'' to a single scalar value each time.  Without the brackets, ''n'' is passed down as an array.
Definition:
 
  Var n := start;
 
  Var steps := 0;
 
  While n>1 do (
 
      n := If Mod(n,2)=0 then n/2 else 3*n+1;
 
      steps := steps + 1
 
  )
 
  
= While Any ''cond'' Do =
+
The [[While..Do]] construct is used most often from within [[User-Defined Functions]].  In this case, the dimensionality declaration should be placed on the [[Function Parameter Qualifiers]].  In this case, we would declare the parameter <code>start</code> to be atomic:
  
When the condition evaluates to an array, the keyword ''Any'' can be specified to indicate that the while loop is to continue as long as any of the elements of the array is non-zero.  Example:
+
:<code>Function Num3nSteps(start: atomic)</code>
 +
:<code>Definition:</code>
 +
::<code>Local n := start;</code>
 +
::<code>Local steps := 0;</code>
 +
::<code>While n > 1 do (</code>
 +
:::<code>n := If Mod(n, 2) = 0 then n/2 else 3*n + 1;</code>
 +
:::<code>steps := steps + 1</code>
 +
::<code>)</code>
  
[[Var]] steps := 0;
+
== While Any ''cond'' Do ==
[[Var]] x := start;
+
When the condition evaluates to an array, the keyword '''Any''' can be specified to indicate that the while loop is to continue as long as any of the elements of the array is non-zero. Example:
While Any x>1 Do (
 
  steps := [[If]] x>1 [[Then]] steps+1 [[Else]] steps;
 
  x := [[If]] x<2 [[Then]] x
 
        [[Else]] [[If]] [[Mod]](x,2)=0 [[Then]] x/2
 
        [[Else]] 3*x+1;
 
  );
 
steps
 
  
In general, Any iterates most elements more times than necessary in order to handle extra dimensions.
+
:<code>Local steps := 0;</code>
 +
:<code>Local x := start;</code>
 +
:<code>While Any x > 1 Do (</code>
 +
::<code>steps := If x > 1 Then steps + 1 Else steps;</code>
 +
::<code>x := If x < 2 Then x</code>
 +
:::<code>Else If Mod(x, 2) = 0 Then x/2</code>
 +
:::<code>Else 3*x + 1;</code>
 +
:<code>);</code>
 +
:<code>steps</code>
  
= See Also =
+
In general, '''Any''' iterates most elements more times than necessary in order to handle extra dimensions.
  
 +
== See Also ==
 
* [[Iterate]]
 
* [[Iterate]]
 
* [[For..Do]]
 
* [[For..Do]]

Latest revision as of 18:49, 24 May 2021


While (test) Do body

While evaluates «body» repeatedly as long as «test» <> 0.

In order for While to terminate, «body» must produce a side-effect on a local variable that is used by «test», causing «test» eventually to equal 0. If «test» never becomes false, While continues to loop indefinitely. If you suspect that might be happening, type Control+Break or Control+. (Control+period) to interrupt evaluation.

While returns the final value found in the last iteration of «body», or Null if no iterations occur.

«Test» must evaluate to an atomic (non-array) value; therefore, it is a good idea to force any local variable used in «test» to be atomic valued. While is one of the few constructs in Analytica that does not generalize completely to handle arrays. But, there are ways to ensure that variables and functions using While support Intelligent Arrays and probabilistic evaluation.

Examples

Local n := 1;
While n < 1000 do n := 2*n
n → 1024
Local x := 1;
Local prev := 0;
while Abs(x - prev) > 1e-6 do (
prev := x ;
x := 1 + 1/(1 + x)
)
x → 1.414214

Array Abstraction with While

The While construct is one of a few constructs in Analytica that does not fully array abstract. The limitation arises from the fact that «test» must be a scalar value, i.e., it cannot be array valued. Consider, for example, the following expression:

Local n := start;
Local steps := 0;
While n > 1 do (
n := If Mod(n, 2) = 0 then n/2 else 3*n + 1;
steps := steps + 1
)

If start = 20 when this is evaluated, this returns 7 (n steps through values of 20, 10, 5, 16, 8, 4, 2, 1). If start = 22, it returns 15, and for start = 27 it returns 111. One of the key features of an Analytica model is the ability to easily add a dimension to an input without having to change the model's internals. So what we'd like is that when start is set to the list [20, 22, 27], the expression would array-abstract and return the result array [7, 15, 111]. However, the above expression will result in an error, complaining that «test» is not a scalar.

While disallows «test» to be an array, because otherwise the criteria for termination is ambiguous. It may be that for certain elements, the loop should be terminated, while for others it should not.

These problems can be addressed by declaring the dimensionality of all parameters that influence «test». We can do this simply in this example by listing the dimensions of n when it is declared -- in this case listing zero dimensions, hence there are no index identifiers between the brackets in its declaration:

Local n[ ] := start;
Local steps := 0;
While n > 1 do (
n := If Mod(n, 2) = 0 then n/2 else 3*n + 1;
steps := steps + 1
)

When this is evaluated and start is array-valued, Analytica sees that n must be scalar in the expression that uses n. To accomplish that, Analytica will iterate as necessary, setting n to a single scalar value each time. Without the brackets, n is passed down as an array.

The While..Do construct is used most often from within User-Defined Functions. In this case, the dimensionality declaration should be placed on the Function Parameter Qualifiers. In this case, we would declare the parameter start to be atomic:

Function Num3nSteps(start: atomic)
Definition:
Local n := start;
Local steps := 0;
While n > 1 do (
n := If Mod(n, 2) = 0 then n/2 else 3*n + 1;
steps := steps + 1
)

While Any cond Do

When the condition evaluates to an array, the keyword Any can be specified to indicate that the while loop is to continue as long as any of the elements of the array is non-zero. Example:

Local steps := 0;
Local x := start;
While Any x > 1 Do (
steps := If x > 1 Then steps + 1 Else steps;
x := If x < 2 Then x
Else If Mod(x, 2) = 0 Then x/2
Else 3*x + 1;
);
steps

In general, Any iterates most elements more times than necessary in order to handle extra dimensions.

See Also

Comments


You are not allowed to post comments.