Creating a dynamic function from another function

I have a Fortran 90 routine that takes a function as an argument, and I would like to pass a modified version of this function to another routine. I want the program to look something like this:

subroutine foo(f, ...) real :: pt(2), dir(2) interface function f(x) result(y) real, intent(in) :: x(2) real :: y end function f end interface pt = ... dir = ... !! Somehow create g(x) = f(pt + x*dir) call bar(g) end subroutine foo subroutine bar(g) interface function g(x) result(y) real, intent(in) :: x real :: y end function g end interface !! Do stuff with g end subroutine bar 

I managed to do something like this when "g" needed to use regular variables, not a function. In this case, I made a global function using global variables and assigned these global variables to "foo". However, I cannot find a way to turn the global value of "f" or assign it to a global function.

Anyone have any ideas how to do this? The solution can be either hacked or you.

+4
source share
2 answers

It is not so easy. In some languages, you can pass pointers to nested functions in what is called closure . This is not possible in Fortran (or C and similar languages), since data is destroyed using a stack of a higher function. I suggest you try function objects, i.e. A class with a function pointer (or more) and the data needed for the function. Thus, you can even perform composition of functions and similar functional elements.

Read more on the concept of http://en.wikipedia.org/wiki/Function_object

The following is a sample for a function object to compose two single arguments:

 module ComposeObj use Parameters use AritmFunctions implicit none private public Compose type Compose private procedure(fce),pointer,nopass :: f1 => null(),f2=>null() contains procedure,public :: call => helper endtype Compose interface Compose procedure NewCompose end interface contains function NewCompose(f,g) procedure(fce) :: f,g type(Compose) :: NewCompose NewCompose%f1 => f NewCompose%f2 => g end function NewCompose pure real(KND) function helper(this,x) class(Compose),intent(in) :: this real(KND),intent(in) :: x helper = this%f1(this%f2(x)) end function helper end module ComposeObj 
+5
source

You can do a lot with procedure pointers by creating a function that is a combination of other functions. See Fortran function pointer arrays for sample code.

+2
source

Source: https://habr.com/ru/post/1401250/


All Articles