gpt4 book ai didi

nested - Fortran 嵌套 WHERE 语句

转载 作者:行者123 更新时间:2023-12-05 00:56:46 26 4
gpt4 key购买 nike

我有一个带有嵌套 WHERE 语句的 Fortran 90 源代码。有一个问题,但似乎很难理解到底发生了什么。我想把它转换成DO-IF结构以便调试。我不清楚的是如何翻译嵌套的 WHERE。

所有数组都具有相同的大小。

WHERE (arrayA(:) > 0)
diff_frac(:) = 1.5 * arrayA(:)
WHERE (diff_frac(:) > 2)
arrayC(:) = arrayC(:) + diff_frac(:)
ENDWHERE
ENDWHERE

我的选项A:
DO i=1, SIZE(arrayA)
IF (arrayA(i) > 0) THEN
diff_frac(i) = 1.5 * arrayA(i)
DO j=1, SIZE(diff_frac)
IF (diff_frac(j) > 2) THEN
arrayC(j) = arrayC(j) + diff_frac(j)
ENDIF
ENDDO
ENDIF
ENDDO

我的选项B:
DO i=1, SIZE(arrayA)
IF (arrayA(i) > 0) THEN
diff_frac(i) = 1.5 * arrayA(i)
IF (diff_frac(i) > 2) THEN
arrayC(i) = arrayC(i) + diff_frac(i)
ENDIF
ENDIF
ENDDO

谢谢

最佳答案

根据线程"Nested WHERE constructs "在 comp.lang.fortran (特别是 Ian 的回复) 中,似乎问题中的第一个代码转换为以下内容:

do i = 1, size( arrayA )
if ( arrayA( i ) > 0 ) then
diff_frac( i ) = 1.5 * arrayA( i )
endif
enddo

do i = 1, size( arrayA )
if ( arrayA( i ) > 0 ) then
if ( diff_frac( i ) > 2 ) then
arrayC( i ) = arrayC( i ) + diff_frac( i )
endif
endif
enddo
除了第二个面具部分(见下文)外,这与马克的答案几乎相同。 F2008 的主要摘录文件是这样的:

7.2.3 Masked array assignment – WHERE (page 161)

7.2.3.2 Interpretation of masked array assignments (page 162)

... 2. Each statement in a WHERE construct is executed in sequence.

... 4. The mask-expr is evaluated at most once.

... 8. Upon execution of a WHERE statement that is part of a where-body-construct, the control mask is established to have the value m_c .AND. mask-expr.

... 10. If an elemental operation or function reference occurs in the expr or variable of a where-assignment-stmt or in a mask-expr, and is not within the argument list of a nonelemental function reference, the operation is performed or the function is evaluated only for the elements corresponding to true values of the control mask.


如果我正确理解了上述线程/文档,则条件 diff_frac( i ) > 2arrayA( i ) > 0 之后评估,因此对应于双 IF 块(如果我假设 Fortran 中的 A .and. B 未指定求值顺序)。

但是,如上述线程中所述,实际行为可能取决于编译器...例如,如果我们使用 gfortran5.2、ifort14.0 或 Oracle fortran 12.4(没有选项)编译以下代码
integer, dimension(4) :: x, y, z
integer :: i

x = [1,2,3,4]
y = 0 ; z = 0

where ( 2 <= x )
y = x
where ( 3.0 / y < 1.001 ) !! possible division by zero
z = -10
end where
end where

print *, "x = ", x
print *, "y = ", y
print *, "z = ", z
他们都给出了预期的结果:
x =            1           2           3           4
y = 0 2 3 4
z = 0 0 -10 -10
但是如果我们用调试选项编译
gfortran -ffpe-trap=zero
ifort -fpe0
f95 -ftrap=division (or with -fnonstd)
gfortran 和 ifort 通过评估 y(i) = 0 中止浮点异常在掩码表达式中,而 f95 运行时没有任何提示。 (根据链接的线程,Cray 的行为类似于 gfortran/ifort,而 NAG/PGI/XLF 的行为类似于 f95。)

作为旁注,当我们在 WHERE 构造中使用“非元素”函数时,控制掩码不适用,所有元素都用于函数评估(根据上述草案的第 7.2.3.2 节,第 9 句)。例如,下面的代码
integer, dimension(4) :: a, b, c

a = [ 1, 2, 3, 4 ]
b = -1 ; c = -1

where ( 3 <= a )
b = a * 100
c = sum( b )
endwhere
a =  1 2 3 4
b = -1 -1 300 400
c = -1 -1 698 698
这意味着 sum( b ) = 698 是从 b 的所有元素中获得的,两个语句按顺序计算。

关于nested - Fortran 嵌套 WHERE 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35795971/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com