fortran - 在子例程中传递和使用可选掩码

标签 fortran

我将一个可选掩码传递给子例程。在这个例程中,我有很多类似的陈述

...
if (present(Mask)) then
  where(Mask)
    y(:) = A(:)*B(:)
  end where
else
  y(:) = A(:)*B(:)
end if
...

这在代码重复方面非常难看。有什么建议可以更好地做到这一点吗?我的代码中有很多这样的语句,我需要对整个数组执行操作。

编辑: 至少一部分问题可以通过基本函数来解决。因为我在右侧有相同的操作我可以写

...
if (present(Mask)) then
  where(Mask)
    y(:) = multiply(A(:),B(:))
  end where
else
  y(:) = multiply(A(:),B(:))
end if
...
elemental real function multiply(a,b)
  real, intent(in) :: a,b
  multiply = a*b
end function

这样,我至少有一个单独的操作位置。

最佳答案

有一个选项(双关语)不使用可选参数,而是编写一个通用接口(interface)。例如,不要写

subroutine bar(arg0, opt)
  integer, intent(inout) :: arg0
  integer, intent(in), optional :: opt
  arg0 = int(4 * atan(1.))
  if (present(opt)) arg0 = arg0 + opt
module foo

你可以做到

interface bar
  module procedure bar0
  module procedure bar1
end interface bar

contains

  subroutine bar0(arg0)
     integer, intent(inout) :: arg0
     arg0 = int(4 * atan(1.))
  end subroutine bar0

  subroutine bar1(arg0, opt)
     integer, intent(inout) :: arg0
     integer, intent(in) :: opt
     arg0 = arg0 + opt
  end subroutine bar1

end module foo

program bah
  use foo
  integer :: a0 = 1, a1 = 42
  call bar(a0)
  print *, a0
  call bar(a0, a1)
  print *, a0
end program bah

您可以从这种方法中获得的一个优势是 bar0 bar1 可以让编译器更好地进行优化 代码。 if (present(opt)) 结构可能会妨碍。

关于fortran - 在子例程中传递和使用可选掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62742076/

相关文章:

c - 打开 Watcom Linker 在链接 C 和 Fortran 代码以构建 Matlab mex 文件时发现 undefined reference

检查 iso_c_binding 在编译时是否可用

operator-overloading - 在 Fortran 重载赋值中检查自赋值

arrays - 查看一组值是否出现在数组中的有效方法?

c++ - 如何将字符串数组从 C 和 Fortran 传递给 Fortran?

fortran - Fortran 中的内联函数

fortran - 如何异常停止fortran程序

c - 保持线程存活 (pthread, c)

multidimensional-array - 矩阵的 Fortran 转置不适用于非二维数组

fortran - 在 gdb 中调用 Fortran 内在函数