integrals.f90 Source File


Files dependent on this one

sourcefile~~integrals.f90~~AfferentGraph sourcefile~integrals.f90 integrals.f90 sourcefile~test_integrals.f90 test_integrals.f90 sourcefile~test_integrals.f90->sourcefile~integrals.f90

Source Code

module integrals
  !! module for computing integrals
  implicit none
contains

  function trapz(x,y) result(Int)
    !! Aproximates the integral of the function
    !! $$ y = f(x)$$
    !! given a set of points:
    !! $$(x_i,y_i)$$
    !! using the trapezoidal rule.
    !! The points do not need to be linearly spaced along the
    !! integration domain.
    real, intent(in) :: x(0:)
    !! Array containing the abscissas of the points
    real, intent(in) :: y(0:)
    !! Array containing the ordinates of the points
    real :: Int
    !! Numerical aproximation to the integral

    integer :: i, N

    N = ubound(x,1)
    Int = 0.
    do i = 1,N
      Int = Int + (y(i-1)+y(i))/2*(x(i)-x(i-1))
    end do
  end function




  function quad_trapz(f,a,b,h_in) result(Int)
    !! Approximates the integral:
    !! $$ \int_{a}^{b}f\left(x\right)\,\mathrm{d}x$$
    !! using the trapezoidal rule on a linearly spaced
    !! set of points.
    interface
      function f(x) result(y)
        !! Function to be integrated
        real, intent(in) :: x
        !! independent variable
        real :: y
        !! dependent variable
      end function
    end interface
    real, intent(in) :: a
    !! Lower limit of integration
    real, intent(in) :: b
    !! Upper limit of integration
    real, intent(in) :: h_in
    !! Approximated size of the intervals used by the trapezoidal rule.
    real :: Int
    !! Numerical approximation to the integral

    integer :: i, N
    real :: h, x_l, x_r

    ! imposing that h must divide (b-a) in a whole number
    ! of intervals
    N = ceiling((b-a)/h_in)
    h = (b-a)/N

    Int = 0.
    do i=1,N
      x_l = (i-1)*h
      x_r = i*h
      Int = Int + (f(x_l)+f(x_r))/2
    end do
    Int = Int*h
  end function


function quad_simpson(f,a,b,h_in) result(Int)
  !! Approximates the integral:
  !! $$ \int_{a}^{b}f\left(x\right)\,\mathrm{d}x$$
  !! using Simpson's rule on a linearly spaced
  !! set of points.
  interface
    function f(x) result(y)
      !! Function to be integrated
      real, intent(in) :: x
      !! independent variable
      real :: y
      !! dependent variable
    end function
  end interface
  real, intent(in) :: a
  !! Lower limit of integration
  real, intent(in) :: b
  !! Upper limit of integration
  real, intent(in) :: h_in
  !! Approximated size of the intervals used by the trapezoidal rule.
  real :: Int
  !! Numerical approximation to the integral

  integer :: i, N
  real :: h, x_l, x_m, x_r

  ! imposing that h must divide (b-a) in an even number
  ! of intervals
  N = ceiling((b-a)/h_in)
  if(modulo(N,2)==1) N = N+1
  h = (b-a)/N

  Int = 0.
  do i=1,N,2
    x_l = (i-1)*h
    x_m = i*h
    x_r = (i+1)*h
    Int = Int + (f(x_l)+4*f(x_m)+f(x_r))/3
  end do
  Int = Int*h
end function


function quad(f,a,b,h_in,method) result(Int)
  !! Approximates the integral:
  !! $$ \int_{a}^{b}f\left(x\right)\,\mathrm{d}x$$
  !! using some integration method on a linearly spaced
  !! set of points.
  interface
    function f(x) result(y)
      !! Function to be integrated
      real, intent(in) :: x
      !! independent variable
      real :: y
      !! dependent variable
    end function
  end interface
  real, intent(in) :: a
  !! Lower limit of integration
  real, intent(in) :: b
  !! Upper limit of integration
  real, intent(in) :: h_in
  !! Approximated size of the intervals used by the trapezoidal rule.
  character(*) :: method
  !! Method of integration to be used, can be either "Trapezoidal" or "Simpson"
  real :: Int
  !! Numerical approximation to the integral
  select case (method)
  case ("Trapezoidal")
    Int = quad_trapz(f,a,b,h_in)
  case ("Simpson")
    Int = quad_simpson(f,a,b,h_in)
  case default
    print*, 'Integration method "'//method//'"" not recognised,'
    print*, 'please choose between "Trapezoidal" and "Simpson"'
  end select
end function
end module