Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a subroutine that accepts different kinds of reals

I want to implement a subroutine that can work with reals in single precision, double precision and extended precision. The only solution I can come up with is shown in the code below. This solution works but I have to duplicate the code 3 times. Can this code duplication be avoided?

module mymodule
    ....
    ! some code here

    interface my_func
         module procedure my_func_sp
         module procedure my_func dp
         module procedure my_func_ep
    end interface

contains
    subroutine my_func_sp(x,y)
         real(kind=sp), dimension(:) :: x,y

         ... LONG IMPLEMENTATION HERE ...

    end subroutine

    subroutine my_func_dp(x,y)
         real(kind=dp), dimension(:) :: x,y

         ... LONG IMPLEMENTATION HERE THAT IS EXACTLY THE SAME AS ABOVE ...

    end subroutine


    subroutine my_func_ep(x,y)
         real(kind=ep), dimension(:) :: x,y

         ... LONG IMPLEMENTATION HERE THAT IS EXACTLY THE SAME AS THE TWO ABOVE ...

    end subroutine
end module
like image 238
Erik Avatar asked Dec 14 '25 01:12

Erik


1 Answers

Can this code duplication be avoided? Not really, this is the way Fortran works. You could:

  1. Write the code once, for the highest-precision kind you care about, and have the other subroutines call that variant, casting the kinds of variables on the way in and out.
  2. Another approach I have seen regularly is to write the computational statements in a file and to include that file in each of the subroutines. Just take care that the included statements are valid for all kinds of the type. Take care too that the same statements work across kinds. If, for example, your included lines include comparisons with a tolerance, as many numeric codes do, you may have to take special care that the tolerance is adjusted wrt the kind.
like image 143
High Performance Mark Avatar answered Dec 16 '25 23:12

High Performance Mark



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!