7

我有一个将函数作为参数的 Fortran 90 子例程,我想将该函数的修改版本传递给另一个子例程。我希望程序看起来像这样:

subroutine foo(f, ...)
    real                 :: pt(2), dir(2)

    interface
    function f(x) result(y)
        real, intent(in) :: x(2)
        real             :: y
    end function f
    end interface

    pt = ...
    dir = ...
!! Somehow create g(x) = f(pt + x*dir)
    call bar(g)

end subroutine foo

subroutine bar(g)
    interface
    function g(x) result(y)
        real, intent(in) :: x
        real             :: y
    end function g
    end interface

!! Do stuff with g
end subroutine bar

当'g'只需要使用普通变量而不是函数时,我已经设法做类似的事情。在那种情况下,我使用全局变量将其设为全局函数,并分配给“foo”中的那些全局变量。但是,我找不到将“f”设为全局或将其分配给全局函数的方法。

有人对如何做到这一点有任何想法吗?解决方案可以随心所欲。

4

2 回答 2

7

这并不容易。在某些语言中,您可以将指针传递给所谓的closure. 这在 Fortran(或 C 和类似语言)中是不可能的,因为数据会随着更高函数的堆栈而被破坏。我建议您尝试函数对象,即class带有function pointer(或更多)函数所需的数据和数据。通过这种方式,您甚至可以进行功能组合和类似的功能性工作。

更多关于这个概念http://en.wikipedia.org/wiki/Function_object

下面是用于组合两个单参数函数的函数对象的示例:

module ComposeObj
  use Parameters, only: rp
  use AritmFunctions, only: fce
  implicit none

  private
  public Compose

  type Compose
    private
    procedure(fce),pointer,nopass :: f1 => null(),f2=>null()
  contains
    procedure,public :: call => helper
  end type Compose

  interface Compose
    procedure NewCompose
  end interface

 contains

  function NewCompose(f,g)
    procedure(fce) :: f,g
    type(Compose) :: NewCompose

    NewCompose%f1 => f
    NewCompose%f2 => g
  end function NewCompose

  pure real(rp) function helper(this,x)
    class(Compose),intent(in) :: this
    real(rp),intent(in) :: x
    helper = this%f1(this%f2(x))
  end function helper

end module ComposeObj
于 2012-03-14T08:56:23.877 回答
2

你可以用过程指针做很多事情,构造一个由其他函数组合而成的函数。有关代码示例,请参阅Fortran 中的函数指针数组。

于 2012-03-14T03:56:17.603 回答