If-Then-Else

Revision as of 21:45, 23 July 2009 by Drice (talk | contribs) (Filling in initial content for IF-THEN-ELSE)


If a Then b Else c

This conditional expression evaluates and returns «b» if «a» is true, or «c» if «a» is false.

Variable X := 1M
Variable Y := 1
 
If X > Y Then X Else Y → 1M

Omitting Else

It is possible to omit the Else clause:

If X < Y Then MsgBox("Unexpected: X was found to be less than Y");
X-Y

When the Else clause is omitted and «a» is false, a warning will be issued if the result value is actually used (in the above example, it isn't used, so no warning results). If you ignore the warning, the result is Null.

Uusally, you should omit the Else «c» part only in a compound expression, where Then «b» is followed by a semi-colon, followed by other expressions. In such case, the result of If-Then is not actually used. See also #Perils of Side-Effects below.

Array Parameters

Conditional expressions get more interesting when they work on arrays, in which case array-abstraction generalizes to multi-dimensional cases. When «a» is an array with a mixture of true and false values, the result is an array with the same indexes as «a», which individual cells containing «b» or «c» as appropriate.

Variable x := -2..2
 
If x>0 Then 'Positive'
Else If x<0 Then 'Negative'
Else 'Zero'
If then else1.jpg

If «b» or «c» are arrays with the same indexes as «a», the corresponding values from «b» or «c» are returned according to whether «a» is true or false.

If x>=0 Then Sqrt(x) Else 'Imaginary'
If then else2.jpg

When «b» and «c» are evaluated

If-Then-Else processes all its parameters using array operations. The full arrays for «b» is computed whenever «a» contains at least one true value. So in the earlier example:

If X>=0 Then Sqrt(x) Else 'Imaginary'

the square root of x is computed even for the negative values of X, even though they are replaced with 'Imagingary in the final result. Similarly, if «a» contains at least one false value, then «c» is computed entirely, even for values where «a» is true.

The apparently wasted computation is usually more than offset by the faster computation obtained from Analytica's ability to process the expressions using array processing. However, this not always true, and in some cases a case failing the antecedent condition can lead to an error when «b» (or «c») is evaluated.

To avoid evaluating «b» or «c»

The entire evaluation of «b» is skipped (i.e., the expression for «b» is not evaluated at all) when «a» is scalar false, or is an array containing only false values. Likewise, «c» is not evaluated when «a» is scalar true or when «a» is an array containing only true values.

To avoid computations for sub-arrays of «b» (or of «c»), you must employ explicit iteration (via User-Defined Functions using Parameter Dimensionality Qualifiers. Usually the iteration is writen in such a way to ensure that «a» is a scalar each time the conditional is processed.

Var xi[] := x Do 
   If xi>=0 Then Sqrt(xi) Else 'Imaginary'

The overhead of explicit iteration may slow down computation substantially. As long as you aren't experiencing errors, in the vast majority of cases it is better to simply let «b» and «c» be evaluated in full.

Embedded Warnings

When Sqrt(x) is evaluated on a negative number, an embedded warning is issued. When that warning occurs from within an expression embedded in «b» or «c», it might have no effect on the final result if «a» doesn't select it. When the embedded warning occurs, Analytica figures out whether the warning could potentially impact the final result, or whether it will end up being ignored. When Analytica concludes that the case generating the warning does not impact the final result, then the warning is not shown to the the user, even if Show Result Warnings is on. This logic makes it possible for you to write very intuitive expressions to avoid problematic cases, as was done with the Sqrt example above; however, the logic to determine whether the warning will impact the final result does consume computational cycles. If you determine a particular computation involving If-then-else, where embedded warnings are probably occurring within «b» or «c», a speed-up can be obtained by surrounding the expression with a call to IgnoreWarnings():

IgnoreWarnings( If x>=0 Then Sqrt(x) else 'Imaginary' )

In this example, no change to behavior occurs, but speed-up occurs because the extra process to determine whether the case generating the warning is eventually ignored is skipped.

Perils of Side-Effects

Extreme care should be exercised when using Assignment Operators within conditionals. When dealing with array cases, assignment occuring within «b» or «c» is likely to produce counter-intuitive results.

Comments


You are not allowed to post comments.