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.
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
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With