Function as an output argument

假装没事ソ 提交于 2019-12-08 18:56:24

问题


I want to create a subroutine that gives back a function as an output. How can I do that? I'll put an example of how I think it should be (I know it's badly written)

module fun_out

contains

subroutine exponential(F,a)
     interface, intent(out)

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

   F=exp(a*x)

end subroutine exponential

end module

With this I should take a function from the exponential family in the output.


回答1:


You would have to return a function pointer. That can be done in Fortran 2003.

   procedure(name_of_interface), pointer :: f

You must however not expect full lexical scope closures, just pure pointers.

You must have the procedure prepared as a normal external, module or in F2008 even internal procedure (with some limitations) and just point to it:

    f => my_function

In your case you have the argument a, and you seem to want to use it a captured closure variable. It is not possible in Fortran. You either have to pass it every time to the function, or us the Functor pattern (derived type holding the captured parameters), or use an internal procedure (but that would be valid only inside its host procedure).




回答2:


You can basically do that (as also mentioned in Vladimir's answer) with defining functor objects. They have one specific function returning the value (e.g. getvalue()), and depending on their initialization, they may return customized function values.

The example below demonstrates that in detail. The general functor is defined in functor_module, in expfunc_module a concrete realization for the exponential function family is derived. Then, in the main program then you initialize different instances with different prefactors in the exponents and can use their getvalue() method to obtain the appropriate function values.:

module functor_module
  implicit none

  integer, parameter :: wp = kind(1.0d0)

  type, abstract :: functor
  contains
    procedure(getvalue_iface), deferred :: getvalue
  end type functor

  interface 
    function getvalue_iface(self, xx) result(yy)
      import
      class(functor), intent(in) :: self
      real(wp), intent(in) :: xx
      real(wp) :: yy
    end function getvalue_iface
  end interface

end module functor_module


module expfunc_module
  use functor_module
  implicit none

  type, extends(functor) :: expfunc
    real(wp) :: aa
  contains
    procedure :: getvalue
  end type expfunc

contains

  function getvalue(self, xx) result(yy)
    class(expfunc), intent(in) :: self
    real(wp), intent(in) :: xx
    real(wp) :: yy

    yy = exp(self%aa * xx)

  end function getvalue

end module expfunc_module


program test_functors
  use expfunc_module
  implicit none

  type(expfunc) :: func1, func2
  real(wp) :: xx

  func1 = expfunc(1.0_wp)
  func2 = expfunc(2.0_wp)
  xx = 1.0_wp
  print *, func1%getvalue(xx)   ! gives exp(1.0 * xx) = 2.718...
  print *, func2%getvalue(xx)   ! gives exp(2.0 * xx) = 7.389...

end program test_functors


来源:https://stackoverflow.com/questions/19675891/function-as-an-output-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!