0

I would like to write a Fortran function that takes another function as input. I know that I can do this via an interface. From now on I will call these two different functions the 'function' and the 'interfaced function'.

Imagine that my function only varies the first argument of the interfaced function. For example, it might be an integration routine that is integrating in x, which is the first argument of any interfaced function that I would pass to it.

I would like to be able to pass an interfaced function with any number of arguments to this first function, and somehow be able to set fixed constant values for any other arguments that the interfaced function requires. A minimal example of the type of thing I want is below:

PROGRAM test

  IMPLICIT NONE

  !This works
  WRITE(*,*) add(g)

  !This does not work
  WRITE(*,*) add(h(:,0.))

CONTAINS

  REAL FUNCTION add(f)

    IMPLICIT NONE

    INTERFACE
       REAL FUNCTION f(x)
         REAL, INTENT(IN) :: x
       END FUNCTION f
    END INTERFACE

    add=f(1.)+f(2.)

  END FUNCTION add

  REAL FUNCTION g(x)

    IMPLICIT NONE
    REAL, INTENT(IN) :: x

    g=x**2

  END FUNCTION g

  REAL FUNCTION h(x,y)

    IMPLICIT NONE
    REAL, INTENT(IN) :: x, y

    h=x**2+y**2

  END FUNCTION h

END PROGRAM test

The above code will not compile with the second add call in the main program and complains of a syntax error in the argument list. However, it works fine without this line.

Is there any way I can adjust my code so that I can call my add function with the input h function as well as with the input g function?

Note that the actual application I have in mind for this is relatively complex, and involves 'interfaced functions' that would need all sorts of different types in their argument list.

Mead
  • 383
  • 4
  • 19
  • Another one which can't be added to the list https://stackoverflow.com/questions/24391991/in-fortran-90-how-do-i-program-the-equivalent-of-a-handle-in-matlab?noredirect=1&lq=1 and tgere are more. – Vladimir F Героям слава May 15 '18 at 05:04
  • The immediate error cames from the syntax `h(:,0)` which does not exist. First, it is a function call, not passing a function. Second, you cannot call a function with `:`. I hpe the links show enough methods how to do that differently. Fortran does not have lambdas and uses wrappers. Inttrnal functions or module functions, that does not matter. – Vladimir F Героям слава May 15 '18 at 05:06
  • Okay, so I can create a new function ```wrap_h(x)``` but this necessitates a global variable that then assigns the value to ```y``` in the new ```wrap_h``` function. Is there any way to create this wrapper without a global variable? – Mead May 15 '18 at 05:23
  • The links above show how to do it with an internal function. There is only a variable local to the calling function there, no global variable. – Vladimir F Героям слава May 15 '18 at 05:52
  • I don't think there is another approach not discussed in the links above. In particular there are no closures that would capture variable values in Fortran. I do miss them, but they simply are not available. – Vladimir F Героям слава May 15 '18 at 05:58

0 Answers0