Reputation: 43
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,...)
.
Upvotes: 4
Views: 2183
Reputation: 33
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
Upvotes: 2
Reputation: 59998
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.
Upvotes: 4