问题
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 ?
回答1:
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
回答2:
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.
回答3:
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