使用函数作为参数 - 如何调用?

时间:2018-01-07 17:53:00

标签: function fortran function-parameter

我有以下代码,我从一个子程序调用一个函数,所有这些都在同一个模块中:

      module mymodule
      implicit none
      contains  

      subroutine mycode
      real :: y0(3), a = 0.0, b = 1.0
      integer :: i, N = 10
      real, allocatable :: y(:,:)
      y0(:) = [1.0, 1.0, 1.0]
      y = AB2(od, a, b, N, y0)
      do i = 1, N
          print *, y(:,i)
      end do      
      end subroutine mycode

      function AB2(f, a, b, N, y0)
          real, allocatable :: AB2(:,:)
          interface
              function f(x, y)
                  real, allocatable :: f(:)
                  real, intent(in) :: x, y(:)
              end function
          end interface
          real, intent(in) :: a, b
          integer, intent(in) :: N
          real, intent(in) :: y0(:)
          real :: xn0, xn1, step
          real, allocatable :: yn0(:), yn1(:)
          integer :: i
          allocate(AB2(size(y0),N))
          step = (b-a)/(N-1)
          AB2(:,1) = y0
          AB2(:,2) = y0 + step*f(a, y0)
          do i = 3, N
              xn0 = a+(i-2)*step
              xn1 = a+(i-1)*step
              yn0 = AB2(:,i-2)
              yn1 = AB2(:,i-1)
              AB2(:,i) = AB2(:,i-1) + step*(3.0/2.0*f(xn1,yn1)
     &             -0.5*f(xn0,yn0))
          end do
      end function

      function od(x, y)
          real, allocatable :: od(:)
          real, intent(in) :: x, y(:)
          allocate(od(3))
          od(1) =  x + y(1)
          od(2) = -y(3) - y(2) - x
          od(3) =  x - y(1) + y(3)
      end function

      end module mymodule

如果我想给函数od提供另一个参数,比如说c,我必须把它包含在这一行

real, intent(in) :: x, c, y(:)

以及

   function od(x,c,y)

但是,我在哪里提供此参数的值?通话中没有选项

y = AB2(od, a, b, N, y0)

1 个答案:

答案 0 :(得分:0)

此答案不会尝试复制Fortran minimization of a function with additional arguments Passing external function of multiple variables as a function of one variable in FortranImplementing anonymous functions in Fortran的答案,而是在最基本的层面上介绍问题。

假设您有一个函数AB2和另一个小函数od

它们以AB2接受od作为参数的方式使用,因此您可以调用

y = AB2(od)

函数看起来像

real function AB2(f)
  interface
    real function f(x)
      real x
    end function
  end interface
  ... call f(x) here ...
end function

real function od(x)
  real x
end function

您需要将其他数据c传递给od。怎么做?

您不能仅通过为od添加参数来更改c并保持AB2不变。 AB2包含参数f的界面的说明,而od(x,c)f(x)不兼容。

此外,您无法将数据传递给AB2。你当然做不到

y = AB2(od(c))

通过调用od(c)来计算一个数字,然后尝试将此数字传递给od(x)而不是应该传递的函数。

有几种方法可以缓解这个问题。它们在上面链接的答案中描述。我将展示一个简单的可能性。

我们说我们中心有功能AB2,我们需要将od(b,x)传递给c,但我们不知道如何使用b {1}}。

AB2

在我们的调用代码中,我们创建了一个包装函数,为我们调用 real function od(b,x) real b, x end function od。它可以是内部函数或模块函数。我们将c传递给wrapper

AB2