WHERE 構文は、配列式および配列割り当ての計算をマスクします。 これは論理配列式の値に応じて実行されます。
.--------------------------. V | >>-WHERE_construct_statement----+----------------------+-+------> '-where_body_construct-' .----------------------------. .---------------------. V | V | >----+------------------------+-+----+-----------------+-+------> '-masked_ELSEWHERE_block-' '-ELSEWHERE_block-' >--END_WHERE_statement----------------------------------------->< |
>>-+-where_assignment_statement-+------------------------------>< | (1) | +-WHERE_statement------------+ | (2) | '-WHERE_construct------------' 注:
|
+---------------------------------Fortran 95---------------------------------+
>>-masked_ELSEWHERE_statement--+----------------------+-------->< '-where_body_construct-' |
+-----------------------------End of Fortran 95------------------------------+
>>-ELSEWHERE_statement--+----------------------+--------------->< '-where_body_construct-' |
規則:
+---------------------------------Fortran 95---------------------------------+
+-----------------------------End of Fortran 95------------------------------+
マスクされた配列割り当ての解釈方法を理解するには、 制御マスク (mc) および 保留制御マスク (mp) の 概念について理解する必要があります。
マスクされた
ELSEWHERE ステートメント
ごとに 1 度だけ評価します。
またはマスクされた
ELSEWHERE ステートメント
によって定義されていない配列エレメント上の同じネスト・レベルである、次のマスクされた
割り当てステートメントに情報を提供します。
以下は、コンパイラーが WHERE、WHERE 構文、
マスクされた
ELSEWHERE
、ELSEWHERE、または END WHERE ステートメント内のステートメントの集まりをどのように解釈しているかを
説明しています。
ここでは mc や mp、およびこれ以外のステートメントの動作に与える影響について、発生の順番に説明しています。
+---------------------------------Fortran 95---------------------------------+
+-----------------------------End of Fortran 95------------------------------+
+---------------------------------Fortran 95---------------------------------+
+-----------------------------End of Fortran 95------------------------------+
+---------------------------------Fortran 95---------------------------------+
以下のことが起きます。
+-----------------------------End of Fortran 95------------------------------+
以下のことが起きます。
コンパイラーが END WHERE ステートメントを実行した後、mc と mp は、 対応する WHERE 構文ステートメントの実行前に持っていた値を持ちます。
コンパイラーは、mc の真の値に対応する expr の値を、 対応する variable のエレメントに割り当てます。
非エレメント型関数参照が where_assignment_statement 内の expr または variable、または mask_expr にある場合、コンパイラーはマスクされた制御なしで関数を評価します。 つまり、完全に関数の引き数式のすべてを評価し、それによって完全に関数を評価します。 結果が配列で、参照が非エレメント型関数の引き数リストの範囲内にない場合、コンパイラーは、 expr、variable、または mask_expr の計算に使用するために mc 内の真の値に対応する エレメントを選択します。
エレメント型の組み込み演算または関数参照が where_assignment_statement または mask_expr の expr または variable で発生し、 非エレメント型関数参照の引き数リストの範囲内にない場合、コンパイラーは、mc 内の真の値に対応するエレメントに対してのみ、 演算を実行するか、あるいは関数を評価します。
配列コンストラクターが where_assignment_statement または mask_expr に表示される場合、コンパイラーは 配列コンストラクターを、マスクされた制御なしで評価し、それから where_assignment_statement を実行するか、または mask_expr を評価します。
WHERE ステートメントの mask_expr 内の関数参照を実行することによって、 where_assignment_statement 内のエンティティーに影響を与えることができます。 END WHERE を実行しても、影響はありません。
以下の例は、制御がマスクされ更新される方法を示しています。 この例で、mask1、mask2、mask3、 および mask4 は適合論理配列で、 mc は制御マスクで、mp は保留制御マスクです。 コンパイラーはそれぞれのマスク式を一度評価します。
サンプル・コード (コメント内にステートメント番号を示しています)
WHERE (mask1) ! W1 * WHERE (mask2) ! W2 * ... ! W3 * ELSEWHERE (mask3) ! W4 * ... ! W5 * END WHERE ! W6 * ELSEWHERE (mask4) ! W7 * ... ! W8 * ELSEWHERE ! W9 ... ! W10 END WHERE ! W11
以下に示すとおり、コンパイラーは制御および保留制御マスクを、 それぞれのステートメントを実行するごとに設定します。
+---------------------------------Fortran 95---------------------------------+
+-----------------------------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
コンパイラーは、ステートメント W2、W4、W7、 および W9 によって設定された制御マスクの値を、 それぞれ where_assignment_statement の W3、W5、W8、および W10 を実行するときに使用します。
マイグレーションのためのヒント: 配列の論理計算を単純化します。 FORTRAN 77 ソース: INTEGER A(10,10),B(10,10) Fortran 90 または Fortran 95 ソース: INTEGER A(10,10),B(10,10) |
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---------------------------------+
以下の例は、WHERE 構文ステートメント内およびマスクされた 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
以下の例は、ネストされた WHERE 構文ステートメントおよびマスクされた ELSEWHERE ステートメントに 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------------------------------+