Passing external function of multiple variables as

2019-01-03 11:20发布

I'm trying to use routines in QUADPACK to perform numerical integration. The routines expect functions to be passed as REAL,EXTERNAL, so I don't have the liberty of using pointers or whatever else.

Is it possible to alias a function f(x,a,b,...) as being a function f(x) for the routine that expects a function of x only? Much like what one would accomplish in MATLAB with @(x)f(x,a,b,...).

2条回答
聊天终结者
2楼-- · 2019-01-03 11:38

You cannot make similar tricks with functions in Fortran directly. You also cannot return a closure in Fortran. Just write a wrapper.

function wrap_f(x) result(res)
  ...
  res = f(a,b,...)
end function

It can be an internal or module function and get a and b by the host association or it can use the module containing a and b.

If you want to pass the function as an actual argument, it cannot be an internal procedure in up to Fortran 2003, but only in Fortran 2008. But it works in recent versions of gfortran and ifort. For better portability use a module.

查看更多
在下西门庆
3楼-- · 2019-01-03 11:46

I can show a nice solution for this problem. I am also a former MATLAB user and when switching to FORTRAN you miss function handles haha. I solved your problem in this way:

module

     private
     public    :: f , g

     real(kind=RP)   :: a0,b0,c0,...

     contains
         function f(x,a,b,c,d,...) 
               implicit none
               real(kind=RP)  :: x,a,b,c,d,...
               real(kind=RP)  :: f
!              Here you define your function
               f = ...

         end function f

         function g(x)
               implicit none
               real(kind=RP)  :: x , g

!              Here you call "f" function with the frozen variables *0
               g = f(x,a0,b0,c0,...)
         end function g

!        We said that parameters were private 
!     (to avoid to be modified from the outside, which can be dangerous, 
!     so we define functions to set their values

         subroutine setValues(a,b,c,...)
               implicit none
               real(kind=RP)   :: a,b,c,...

               a0 = a
               b0 = b
               c0 = c

          end subroutine setValues



end module 
查看更多
登录 后发表回答