Interpolation_M.F90 Source File


Contents

Source Code


Source Code

!--------------------------------------------------------------------
! FortranUtilities
!--------------------------------------------------------------------

MODULE FU_Interpolation
   !! author: Emilio Castro.
   !! date: 24/11/2022.
   !! version: 1.0.
   !! license: MIT.
   !! summary: Functions to perform interpolation.
   !! Functions to perform interpolation.

   USE FU_Prec

   IMPLICIT NONE

   PRIVATE
   PUBLIC :: lin_interp

   INTERFACE lin_interp
      !! author: Emilio Castro.
      !! date: 24/11/2022.
      !! version: 1.0.
      !! license: MIT.
      !! summary: Performs linear interpolation.
      !! Performs linear interpolation between the two nearest points in the dataset.
      !!
      !!### Syntax
      !!
      !!```Fortran
      !! y = lin_interp(x, known_xs, known_ys)
      !!```
      !!
      !! Where:
      !!
      !! * `x`: Data point to be predicted.
      !! * `known_xs`: Independent array of data, known X values.
      !! * `known_ys`: Dependent array of data, known Y values.
      !! 
      !! It returns the predicted value y at position x, by linear interpolation
      !! between the nearest points to x in known_xs.
      !!
      !! If `known_xs` and `known_ys` do not have the same size, it will return nan.
      !! If `known_xs` is not ascending ordered, it will return nan.
      !!
      !! Note that this function does not extrapolate.
      !! * If x is lower than known_xs(1), the returned value will be known_ys(1).
      !! * If x is larger than known_xs(N), the returned value will be known_ys(N), where
      !! N is the last index in the arrays.
      !!
      !!### Example
      !!
      !! The following program performs a linear interpolation:
      !!
      !!```Fortran
      !! PROGRAM lin_interpExample
      !!    USE FU_Interpolation, ONLY: lin_interp
      !!    IMPLICIT NONE
      !!    REAL,DIMENSION(6) :: X = (/1., 2., 3., 4., 5., 6./)
      !!    REAL,DIMENSION(6) :: Y = (/0.9, 2.6, 4.3, 8.2, 10.0, 11.1/)
      !!    WRITE(*,*) lin_interp(4.4., X, Y)
      !! END PROGRAM lin_interpExample
      !!```
      MODULE PROCEDURE lin_interp_sp
      MODULE PROCEDURE lin_interp_dp
#ifdef QPREC_FPP
      MODULE PROCEDURE lin_interp_qp
#endif
   END INTERFACE lin_interp

   CONTAINS

   PURE FUNCTION lin_interp_sp(x, known_xs, known_ys) RESULT(y)
      USE FU_statistics, ONLY: linreg
      USE FU_Arrays, ONLY: is_ordered
      IMPLICIT NONE
      INTEGER, PARAMETER :: prec = sp
      REAL(KIND=prec), INTENT(IN) :: x
      !! Data point to be predicted
      REAL(KIND=prec), DIMENSION(:), INTENT(IN) :: known_xs
      !! Independent array of data, known X values.
      REAL(KIND=prec), DIMENSION(:), INTENT(IN) :: known_ys
      !! Dependent array of data, known Y values.
      REAL(KIND=prec) :: y
      !! Predicted value at position x
      INTEGER :: i_1, i_2, siz
      REAL(KIND=prec) :: a, b, R2
      REAL(KIND=prec) :: zero

      
      INCLUDE 'Interpolation_M/include_lin_interp.f90'
      
   END FUNCTION lin_interp_sp

   PURE FUNCTION lin_interp_dp(x, known_xs, known_ys) RESULT(y)
      USE FU_statistics, ONLY: linreg
      USE FU_Arrays, ONLY: is_ordered
      IMPLICIT NONE
      INTEGER, PARAMETER :: prec = dp
      REAL(KIND=prec), INTENT(IN) :: x
      !! Data point to be predicted
      REAL(KIND=prec), DIMENSION(:), INTENT(IN) :: known_xs
      !! Independent array of data, known X values.
      REAL(KIND=prec), DIMENSION(:), INTENT(IN) :: known_ys
      !! Dependent array of data, known Y values.
      REAL(KIND=prec) :: y
      !! Predicted value at position x
      INTEGER :: i_1, i_2, siz
      REAL(KIND=prec) :: a, b, R2
      REAL(KIND=prec) :: zero

      
      INCLUDE 'Interpolation_M/include_lin_interp.f90'
      
   END FUNCTION lin_interp_dp

#ifdef QPREC_FPP
   PURE FUNCTION lin_interp_qp(x, known_xs, known_ys) RESULT(y)
      USE FU_statistics, ONLY: linreg
      USE FU_Arrays, ONLY: is_ordered
      IMPLICIT NONE
      INTEGER, PARAMETER :: prec = qp
      REAL(KIND=prec), INTENT(IN) :: x
      !! Data point to be predicted
      REAL(KIND=prec), DIMENSION(:), INTENT(IN) :: known_xs
      !! Independent array of data, known X values.
      REAL(KIND=prec), DIMENSION(:), INTENT(IN) :: known_ys
      !! Dependent array of data, known Y values.
      REAL(KIND=prec) :: y
      !! Predicted value at position x
      INTEGER :: i_1, i_2, siz
      REAL(KIND=prec) :: a, b, R2
      REAL(KIND=prec) :: zero

      
      INCLUDE 'Interpolation_M/include_lin_interp.f90'
      
   END FUNCTION lin_interp_qp
#endif

END MODULE FU_Interpolation