This question already has an answer here:
I have a Fortran90 function f(a,b). I need to use a 1D root finder that requires a function g(a), with only one variable a, to find the roots of f for various values of b.
In Matlab, I can build a new function g with only one variable a, with parameter b,
g = @(a) f(a, b);
with b being a parameter that can change in the main program and has scope in f also.
How can I do this in Fortran 90 or 95 ?
Simple: use a wrapping function... If this is your original function f
:
integer function f(a,b)
implicit none
integer,intent(in) :: a, b
f = a + b
end function
You could wrap it into a one-argument-function wrapper_fct
with constant b1
like this:
integer function wrapper_fct(a)
implicit none
integer,intent(in) :: a
integer,parameter :: b1 = 10
wrapper_fct = f(a, b10)
end function
or, even simpler:
integer function wrapper_fct(a)
implicit none
integer,intent(in) :: a
wrapper_fct = f(a, 10)
end function
A quick and dirty example for a wrapper would be the following:
program omhulsel
implicit none
print *, 'f(1.,2.,3.) = ', f(1.,2.,3.)
print *, 'g(1.) = ', g(1.)
print *, 'g(1.,2.,3.) = ', g(1.,2.,3.)
print *, 'g(1.) = ', g(1.)
print *, 'g(1.,b=0.) = ', g(1.,b=0.)
contains
real function f(x,y,z)
real :: x, y, z
f = x**2 + y**2 + z**2
end function
real function g(x,a,b)
real :: x
real, optional :: a, b
real :: par_a = 0, par_b = 0
if (present(a)) par_a = a
if (present(b)) par_b = b
g = f(x,par_a,par_b)
end function
end program
The function g
retains its parameters par_a
and par_b
(they get the SAVE
attribute) which can also be modified by passing along optional arguments.
You can handle this as follows, although it is not fully equivalent to matlab's function handle (functions are not really first-class citizens in Fortran).
module roots
implicit none
contains
subroutine root_finder(f,b)
procedure(func) :: f
real, intent(in) :: b
abstract interface
real function func(a,b)
real, intent(in) :: a,b
end function
end interface
print*, g(2.)
contains
real function g(a)
real, intent(in) :: a
g = f(a,b)
end function
end subroutine
end module
As you can see, the function of two variables is passed to the subroutine, along with the parameter b
. The subroutine uses an internal function g(a)
to evaluate f(a,b)
. This function is, as it were, the "handle".
An example program, which defines an actual function f(a,b) = a**2 + b
:
program example
use roots
implicit none
call root_finder(f, 10.)
contains
real function f(a,b)
real,intent(in) :: a,b
f = a**2 + b
end function
end program
Output: 14.0000000
来源:https://stackoverflow.com/questions/24391991/in-fortran-90-how-do-i-program-the-equivalent-of-a-handle-in-matlab