[英]Do loop inside a where block in Fortran
Even though I do not exactly know why, it seems that Fortran (90) does not allow do
loops inside where
blocks.尽管我不完全知道为什么,但似乎 Fortran (90) 不允许在
where
块内do
循环。 A code structured as follows does not compile with gfortran
( Unexpected DO statement in WHERE block at (1)
):如下结构的代码不能用
gfortran
编译( Unexpected DO statement in WHERE block at (1)
):
real :: a(30), b(30,10,5)
integer :: i, j
do i=1,10
where(a(:) > 0.)
! do lots of calculations
! modify a
do j=1,5
b(:,i,j)=...
enddo
endwhere
enddo
The only workaround that I can think of would be我能想到的唯一解决方法是
real :: a2(30)
do i=1,10
a2(:)=a(:)
where(a(:) > 0.)
! do lots of calculations
! modify a
endwhere
do j=1,5
where(a2(:) > 0.)
b(:,i,j)=...
endwhere
enddo
enddo
I suppose that there are more elegant solutions?我想有更优雅的解决方案? Especially if the
where
condition is less straightforward, this will look messy pretty soon... Thanks!特别是如果
where
条件不那么简单,这很快就会看起来很乱......谢谢!
If your arrays are all 1-indexed, you can replace where
constructs by explicitly storing and using array masks, for example如果您的 arrays 都是 1-indexed,您可以通过显式存储和使用数组掩码来替换
where
构造,例如
program test
implicit none
real :: a(30), b(30,10,5)
integer :: i, j
integer, allocatable :: mask(:)
do i=1,10
mask = filter(a(:)>0.)
! do lots of calculations
! modify a
do j=1,5
b(mask,i,j)=...
enddo
enddo
contains
! Returns the array of indices `i` for which `input(i)` is `true`.
function filter(input) result(output)
logical, intent(in) :: input(:)
integer, allocatable :: output(:)
integer :: i
output = pack([(i,i=1,size(input))], mask=input)
end function
end program
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.