Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to alias a function name in Fortran

Not sure if the title is well put. Suggestions welcome.

Here's what I want to do. Check a condition, and then decide which function to use in a loop. For example:

if (a < 0) then     loop_func = func1 else     loop_func = func2 endif 

I can then use loop_func as a pointer when writing my loop. Both functions take exactly the same inputs, and are different approaches on tackling the problem based on the value of a. This will allow me to only have one block of code, instead of two nearly identical blocks. This could apply to subroutines too.

Any ideas how this might be implemented?

Thank you.

like image 353
Samuel Tan Avatar asked Dec 23 '11 05:12

Samuel Tan


2 Answers

Yes, Fortran has procedure pointers, so you can in effect alias a function name. Here is a code example which assigns to the function pointer "f_ptr" one function or the other. Thereafter the program can use "f_ptr" and the selected function will be invoked.

module ExampleFuncs     implicit none  contains  function f1 (x)   real :: f1   real, intent (in) :: x    f1 = 2.0 * x    return end function f1   function f2 (x)    real :: f2    real, intent (in) :: x     f2 = 3.0 * x**2     return end function f2  end module ExampleFuncs   program test_func_ptrs      use ExampleFuncs     implicit none     abstract interface       function func (z)          real :: func          real, intent (in) :: z       end function func    end interface     procedure (func), pointer :: f_ptr => null ()     real :: input     write (*, '( / "Input test value: ")', advance="no" )    read (*, *) input     if ( input < 0 ) then       f_ptr => f1    else       f_ptr => f2    end if     write (*, '(/ "evaluate function: ", ES14.4 )' )  f_ptr (input)     stop  end program test_func_ptrs 
like image 161
M. S. B. Avatar answered Sep 21 '22 08:09

M. S. B.


Most Fortran implementations do not have a standard way to manipulate function pointers or procedure pointers. However, Fortran 2003 and later have something. (See page 6 of this.)

For the given situation, this will work pretty well in its place:

 function func1 (p1, p2, etc)  ...  as you have it already  end   function func2 (p1, p2, etc)  ...  as you have it already  end   function funcselect (a, p1, p2, etc)      if (a < 0) then           x = func1 (p1, p2, etc)      else           x = func2 (p1, p2, etc)      endif  end 

Then just call funcselect with the extra parameter instead of what you would have done with loop_func.

like image 44
wallyk Avatar answered Sep 18 '22 08:09

wallyk