【问题标题】:Assign fill value to variable if it does not equal to certain values如果变量不等于某些值,则将填充值分配给变量
【发布时间】:2021-12-09 12:54:51
【问题描述】:

我不是 Fortran95 的专业人士,但我正在其中编写代码,我发现如果它没有某些值,我想用 -9999 屏蔽数组值。

示例:我有一个数组“X”的值从 0 到 32768 不等,如果“X”值不等于 0、1、2、16 或 18,我想屏蔽数组的值。我用以下语法解决了它:

if (X.eq.0.or.X.eq.1.or.X.eq.2.or.X.eq.16.or.X.eq.18) then
    X=X
else
    X=-9999
end if

但是在 FORTRAN 95 中还有其他方法可以屏蔽数组值吗?

【问题讨论】:

  • 您说您“有一个数组X”,但您的代码将X 视为标量。

标签: gfortran fortran95


【解决方案1】:

where 语句可以屏蔽数组,但考虑到逻辑你已经表明它有点难看

where (.not.(X==0 || X==1 || X==2 || X==16 || X==18)) x = -9999

【讨论】:

  • 你说得对,我的逻辑有点丑,谢谢你的回答。我尝试了您的解决方案,但它给了我一个括号错误。
【解决方案2】:

对于这类问题,我发现定义 .in. 运算符很方便,它返回标量是否在数组中,所以:

  • 1 .in. [0, 1, 2] 返回.true.
  • 3 .in. [0, 1, 2] 返回.false.
  • [1, 3] .in. [0, 1, 2] 返回[.true., .false.]

这可以定义为

module in_module
  implicit none
  
  interface operator(.in.)
    module procedure element_in_list
    module procedure elements_in_list
  end interface
contains
  function element_in_list(lhs, rhs) result(output)
    integer, intent(in) :: lhs
    integer, intent(in) :: rhs(:)
    logical :: output
    
    output = any(lhs==rhs)
  end function
  
  function elements_in_list(lhs, rhs) result(output)
    integer, intent(in) :: lhs(:)
    integer, intent(in) :: rhs(:)
    logical, allocatable :: output(:)
    
    integer :: i
    
    output = [(any(lhs(i)==rhs), i=1, size(lhs))]
  end function
end module

定义 .in. 运算符后,如果 X 是一个数组,您可以编写

where (.not. (X .in. [0, 1, 2, 16, 18])) X = -9999

这将转换例如X = [4, 5, 1, 3, 16]X = [-9999, -9999, 1, -9999, 16]

如果您想进一步简化事情(因为where 构造可能非常笨拙),您还可以定义函数filter,它接受一个逻辑数组并返回.true. 值的索引,例如filter([.false., .true., .true.]) 返回[2, 3]

这可以定义为:

function filter(input) result(output)
  logical, intent(in) :: input(:)
  integer, allocatable :: output(:)
  
  integer :: i
  
  output = pack([(i, i=1, size(input))], input)
end function

然后你可以简单地写

X(filter(.not. (X .in. [0, 1, 2, 16, 18]))) = -9999

【讨论】:

  • 考虑到要匹配的条件数量,这是一个很好的解决方案。在我的帖子之后,我想到了另一种使用逻辑数组构建掩码的解决方案。 msk = .true.; where(any(x == 0)) msk = .false.; where(any(x==1)) mask = .false.; etc.,最后是where(msk) x = -9999
猜你喜欢
  • 2022-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 1970-01-01
相关资源
最近更新 更多