In fortran 90, how do I program the equivalent of a handle in matlab [duplicate]

一个人想着一个人 提交于 2019-11-26 17:25:00

问题


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

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