XL Fortran for AIX 8.1

Language Reference


WHERE Construct

The WHERE construct masks the evaluation of expressions and assignments of values in array assignment statements. It does this according to the value of a logical array expression.



                              .--------------------------.  .----------------------------.  .---------------------.
                              V                          |  V                            |  V                     |
>>-WHERE_construct_statement----+----------------------+-+----+------------------------+-+----+-----------------+-+--END_WHERE_statement-><
                                '-where_body_construct-'      '-masked_ELSEWHERE_block-'      '-ELSEWHERE_block-'
 
 

WHERE_construct_statement
See WHERE for syntax details.

where_body_construct



>>-+-where_assignment_statement-+------------------------------><
   |                 (1)        |
   +-WHERE_statement------------+
   |                 (2)        |
   '-WHERE_construct------------'
 
 


Notes:


  1. Fortran 95 variable

  2. Fortran 95 variable


where_assignment_statement
Is an assignment_statement.

+---------------------------------Fortran 95---------------------------------+

masked_ELSEWHERE_block



>>-masked_ELSEWHERE_statement--+----------------------+--------><
                               '-where_body_construct-'
 
 

masked_ELSEWHERE_statement
Is an ELSEWHERE statement that specifies a mask_expr. See ELSEWHERE for syntax details.

+-----------------------------End of Fortran 95------------------------------+

ELSEWHERE_block



>>-ELSEWHERE_statement--+----------------------+---------------><
                        '-where_body_construct-'
 
 

ELSEWHERE_statement
Is an ELSEWHERE statement that does not specify a mask_expr. See ELSEWHERE for syntax details.

END_WHERE_statement
See END (Construct) for syntax details.

Rules:

Interpreting Masked Array Assignments

To understand how to interpret masked array assignments, you need to understand the concepts of a control mask (mc) and a pending control mask (mp):

The following describes how the compiler interprets statements in a WHERE, WHERE construct, FORTRAN 95 Beginsmasked ELSEWHERE FORTRAN 95 Ends, ELSEWHERE, or END WHERE statement. It describes the effect on mc and mp and any further behavior of the statements, in order of occurrence.

If a non-elemental function reference occurs in the expr or variable of a where_assignment_statement or in a mask_expr, the compiler evaluates the function without any masked control; that is, it fully evaluates all of the function's argument expressions and then it fully evaluates the function. If the result is an array and the reference is not within the argument list of a non-elemental function, the compiler selects elements corresponding to true values in mc for use in evaluating the expr, variable, or mask_expr.

If an elemental intrinsic operation or function reference occurs in the expr or variable of a where_assignment_statement or in a mask_expr, and is not within the argument list of a non-elemental function reference, the compiler performs the operation or evaluates the function only for the elements corresponding to true values in mc.

If an array constructor appears in a where_assignment_statement or in a mask_expr, the compiler evaluates the array constructor without any masked control and then executes the where_assignment_statement or evaluates the mask_expr.

The execution of a function reference in the mask_expr of a WHERE statement is allowed to affect entities in the where_assignment_statement. Execution of an END WHERE has no effect.

The following example shows how control masks are updated. In this example, mask1, mask2, mask3, and mask4 are conformable logical arrays, mc is the control mask, and mp is the pending control mask. The compiler evaluates each mask expression once.

Sample code (with statement numbers shown in the comments):

WHERE (mask1)        ! W1 *
  WHERE (mask2)      ! W2 *
  ...                ! W3 *
  ELSEWHERE (mask3)  ! W4 *
  ...                ! W5 *
  END WHERE          ! W6 *
ELSEWHERE (mask4)    ! W7 *
...                  ! W8 *
ELSEWHERE            ! W9
...                  ! W10
END WHERE            ! W11
Note:
* Fortran 95

The compiler sets control and pending control masks as it executes each statement, as shown below:

+---------------------------------Fortran 95---------------------------------+


Statement W1
mc = mask1
mp = .NOT. mask1
Statement W2
mp = mask1 .AND. (.NOT. mask2)
mc = mask1 .AND. mask2
Statement W4
mc = mask1 .AND. (.NOT. mask2)
mp = mask1 .AND. (.NOT. mask2)
.AND. (.NOT. mask3)

mc = mask1 .AND. (.NOT. mask2)
.AND. mask3

Statement W6
mc = mask1
mp = .NOT. mask1

+-----------------------------End of Fortran 95------------------------------+


Statement W7
mc = .NOT. mask1
mp = (.NOT. mask1) .AND. (.NOT.
mask4)

mc = (.NOT. mask1) .AND. mask4
Statement W9
mc = (.NOT. mask1) .AND. (.NOT.
mask4)

Statement W11
mc = 0
mp = 0

The compiler uses the values of the control masks set by statements W2, W4, W7, and W9 when it executes the respective where_assignment_statements W3, W5, W8, and W10.



Migration Tip:

Simplify logical evaluation of arrays

FORTRAN 77 source:

INTEGER A(10,10),B(10,10)
     
  ·
  ·
  ·
DO I=1,10 DO J=1,10 IF (A(I,J).LT.B(I,J)) A(I,J)=B(I,J) END DO END DO END

Fortran 90 or Fortran 95 source:

INTEGER A(10,10),B(10,10)
     
  ·
  ·
  ·
WHERE (A.LT.B) A=B END

Examples of the WHERE Construct

REAL, DIMENSION(10) :: A,B,C,D
WHERE (A>0.0)
  A = LOG(A)          ! Only the positive elements of A
                      !   are used in the LOG calculation.
  B = A               ! The mask uses the original array A
                      !   instead of the new array A.
  C = A / SUM(LOG(A)) ! A is evaluated by LOG, but
                      !   the resulting array is an
                      !   argument to a non-elemental
                      !   function. All elements in A will
                      !   be used in evaluating SUM.
END WHERE
 
WHERE (D>0.0)
  C = CSHIFT(A, 1)    ! CSHIFT applies to all elements in array A,
                      ! and the array element values of D determine
                      ! which CSHIFT expression determines the
                      ! corresponding element values of C.
ELSEWHERE
  C = CSHIFT(A, 2)
END WHERE
END

+---------------------------------Fortran 95---------------------------------+

The following example shows an array constructor in a WHERE construct statement and in a masked ELSEWHERE mask_expr:

CALL SUB((/ 0, -4, 3, 6, 11, -2, 7, 14 /))
 
CONTAINS
  SUBROUTINE SUB(ARR)
  INTEGER ARR(:)
  INTEGER N
 
  N = SIZE(ARR)
 
  ! Data in array ARR at this point:
  !
  ! A = | 0 -4 3 6 11 -2 7 14 |
 
  WHERE (ARR < 0)
    ARR = 0
  ELSEWHERE (ARR < ARR((/(N-I, I=0, N-1)/)))
    ARR = 2
  END WHERE
 
  ! Data in array ARR at this point:
  !
  ! A = | 2 0 3 2 11 0 7 14 |
 
  END SUBROUTINE
END

The following example shows a nested WHERE construct statement and masked ELSEWHERE statement with a where_construct_name:

INTEGER :: A(10, 10), B(10, 10)
...
OUTERWHERE: WHERE (A < 10)
  INNERWHERE: WHERE (A < 0)
    B = 0
  ELSEWHERE (A < 5) INNERWHERE
    B = 5
  ELSEWHERE INNERWHERE
    B = 10
  END WHERE INNERWHERE
ELSEWHERE OUTERWHERE
  B = A
END WHERE OUTERWHERE
...

+-----------------------------End of Fortran 95------------------------------+


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]