Copyright Digital Equipment Corp. All rights reserved.

WHERE

 Permits masked array assignment, which lets you perform an array
 operation on selected elements.  This kind of assignment masks the
 evaluation of expressions and assignment of values in array
 assignment statements, according to the value of a logical array
 expression.

 WHERE can be specified as a construct or statement.  Format:

 Statement form:

   WHERE (mask-expr1) assign-stmt 

 Construct form:

   [name :] WHERE (mask-expr1) 
      [where-body-stmt]...
   [ELSEWHERE (mask-expr2) [name]
      [where-body-stmt]...]
   [ELSEWHERE [name]
      [where-body-stmt]...]
   END WHERE [name]

   name             Is the name of the WHERE construct.

   mask-expr1       Are logical array expressions (called 
   mask-expr2       mask expressions).

   assign-stmt      Is an assignment statement of the form: 

                    array variable = array expression

   where-body-stmt  Is one of the following:
                    o An "assign-stmt"
                    o A WHERE statement or construct

 If a construct name is specified in a WHERE statement, the same
 name must appear in the corresponding END WHERE statement.  The
 same construct name can optionally appear in any ELSEWHERE
 statement in the construct.  (ELSEWHERE cannot specify a different
 name.)

 In each assignment statement, the mask expression, the variable
 being assigned to, and the expression on the right side, must all
 be conformable.  Also, the assignment statement cannot be a defined
 assignment.

 Each mask expression in the WHERE construct must be conformable.

 Only the WHERE statement (or the first line of the WHERE construct)
 can be labeled as a branch target statement.

 The following is an example of a WHERE statement:

   INTEGER A, B, C
   DIMENSION A(5), B(5), C(5)
   DATA A /0,1,1,1,0/
   DATA B /10,11,12,13,14/
   C = -1

   WHERE(A .NE. 0) C = B / A

 The resulting array C contains:  -1,11,12,13, and -1.

 The assignment statement is only executed for those elements where
 the mask is true.  Think of the mask expression in this example as
 being evaluated first into a logical array which has the value true 
 for those elements where A is positive.

 This array of trues and falses is applied to the arrays A, B and C
 in the assignment statement.  The right side is only evaluated for
 elements for which the mask is true; assignment on the left side is
 only performed for those elements for which the mask is true.  The
 elements for which the mask is false do not get assigned a value.

 In a WHERE construct the mask expression is evaluated first and
 only once.  Every assignment statement following the WHERE is
 executed as if it were a WHERE statement with "mask-expr1" and
 every assignment statement following the ELSEWHERE is executed as
 if it were a WHERE statement with ".NOT.  mask-expr1".  If
 ELSEWHERE specifies "mask-expr2", it is executed as "(.NOT.
 mask-expr1) .AND.  mask-expr2".

 You should be careful if the statements have side effects, or
 modify each other or the mask expression.

 The following is an example of the WHERE construct:

   DIMENSION PRESSURE(1000), TEMP(1000), PRECIPITATION(1000)
   WHERE(PRESSURE .GE. 1.0)
     PRESSURE = PRESSURE + 1.0
     TEMP = TEMP - 10.0
   ELSEWHERE
     PRECIPITATION = .TRUE.
   ENDWHERE

 The mask is applied to the arguments of functions on the right side
 of the assignment if they are considered to be elemental functions.
 Only elemental intrinsics are considered elemental functions.
 Transformational intrinsics, inquiry intrinsics, and functions or
 operations defined in the subprogram are considered to be
 nonelemental functions.

 Consider the following example using LOG, an elemental function:

   WHERE(A .GT. 0)  B = LOG(A) 

 The mask is applied to A, and LOG is executed only for the positive
 values of A.  The result of the LOG is assigned to those elements
 of B where the mask is true.

 Consider the following example using SUM, a nonelemental function:

   REAL A, B
   DIMENSION A(10,10), B(10)
   WHERE(B .GT. 0.0)  B = SUM(A, DIM=1)

 Since SUM is nonelemental, it is evaluated fully for all of A.
 Then, the assignment only happens for those elements for which the
 mask evaluated to true.

 Consider the following example:

   REAL A, B, C
   DIMENSION A(10,10), B(10), C(10)
   WHERE(C .GT. 0.0)  B = SUM(LOG(A), DIM=1)/C

 Because SUM is nonelemental, all of its arguments are evaluated
 fully regardless of whether they are elemental or not.  In this
 example, LOG(A) is fully evaluated for all elements in A even
 though LOG is elemental.  Notice that the mask is applied to the
 result of the SUM and to C to determine the right side.  One way of
 thinking about this is that everything inside the argument list of
 a nonelemental function does not use the mask, everything outside
 does.