diff --git a/DIRECTORY.md b/DIRECTORY.md index 0fb17e6..296bcaf 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -1,5 +1,11 @@ # The Algorithms - Directory of Fortran ## Maths +* numerical_integration + * [trapezoidal_rule](/modules/maths/numerical_integration/trapezoid.f90) + * [simpson_rule](/modules/maths/numerical_integration/simpson.f90) + * [midpoint_rule](/modules/maths/numerical_integration/midpoint.f90) + * [monte_carlo](/modules/maths/numerical_integration/monte_carlo.f90) + * [gauss_legendre](/modules/maths/numerical_integration/gaussian_legendre.f90) * [euclid_gcd](/modules/maths/euclid_gcd.f90) * [factorial](/modules/maths/factorial.f90) * [fibonacci](/modules/maths/fibonacci.f90) diff --git a/examples/maths/numerical_integration/gaussian_legendre.f90 b/examples/maths/numerical_integration/gaussian_legendre.f90 new file mode 100644 index 0000000..d9935b9 --- /dev/null +++ b/examples/maths/numerical_integration/gaussian_legendre.f90 @@ -0,0 +1,45 @@ +!> Example Program for Gaussian-Legendre Quadrature Module +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #25 +!! https://github.com/TheAlgorithms/Fortran/pull/25 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! +!! This program demonstrates the use of Gaussian-Legendre Quadrature Module for numerical integration. +!! +!! It sets the integration limits and the number of quadrature points (n), and calls the +!! gauss_legendre_quadrature subroutine to compute the approximate value of the definite integral +!! of the specified function. +!! +!! Example function: f(x) = exp(-x^2) * cos(2.0_dp * x) + +program example_gaussian_quadrature + use gaussian_legendre_quadrature + implicit none + + real(dp) :: lower_bound, upper_bound, integral_result + integer :: quadrature_points_number + + ! Set the integration limits and number of quadrature points + lower_bound = -1.0_dp + upper_bound = 1.0_dp + quadrature_points_number = 5 !! Number of quadrature points (order of accuracy) up to 5 + + ! Call Gaussian quadrature to compute the integral with the function passed as an argument + call gauss_legendre_quadrature(integral_result, lower_bound, upper_bound, quadrature_points_number, function) + + write (*, '(A, F12.6)') "Gaussian Quadrature result: ", integral_result !! ≈ 0.858574 + +contains + + function function(x) result(fx) + implicit none + real(dp), intent(in) :: x + real(dp) :: fx + + fx = exp(-x**2)*cos(2.0_dp*x) !! Example function to integrate + end function function + +end program example_gaussian_quadrature diff --git a/examples/maths/numerical_integration/midpoint.f90 b/examples/maths/numerical_integration/midpoint.f90 new file mode 100644 index 0000000..e57a902 --- /dev/null +++ b/examples/maths/numerical_integration/midpoint.f90 @@ -0,0 +1,45 @@ +!> Example Program for Midpoint Rule +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #25 +!! https://github.com/TheAlgorithms/Fortran/pull/25 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! +!! This program demonstrates the use of Midpoint Rule for numerical integration. +!! +!! It sets the integration limits and number of subintervals (panels), and calls the +!! midpoint subroutine to compute the approximate value of the definite integral +!! of the specified function. +!! +!! Example function: f(x) = exp(-x^2) * cos(2.0_dp * x) + +program example_midpoint + use midpoint_rule + implicit none + + real(dp) :: lower_bound, upper_bound, integral_result + integer :: panels_number + + ! Set the integration limits and number of panels + lower_bound = -1.0_dp + upper_bound = 1.0_dp + panels_number = 400 !! Number of subdivisions + + ! Call the midpoint rule subroutine with the function passed as an argument + call midpoint(integral_result, lower_bound, upper_bound, panels_number, function) + + write (*, '(A, F12.6)') "Midpoint rule yields: ", integral_result !! ≈ 0.858196 + +contains + + function function(x) result(fx) + implicit none + real(dp), intent(in) :: x + real(dp) :: fx + + fx = exp(-x**2)*cos(2.0_dp*x) !! Example function to integrate + end function function + +end program example_midpoint diff --git a/examples/maths/numerical_integration/monte_carlo.f90 b/examples/maths/numerical_integration/monte_carlo.f90 new file mode 100644 index 0000000..d4d2776 --- /dev/null +++ b/examples/maths/numerical_integration/monte_carlo.f90 @@ -0,0 +1,45 @@ +!> Example Program for Monte Carlo Integration +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #25 +!! https://github.com/TheAlgorithms/Fortran/pull/25 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! +!! This program demonstrates the use of Monte Carlo module for numerical integration. +!! +!! It sets the integration limits and number of random samples, and calls the +!! monte_carlo subroutine to compute the approximate value of the definite integral +!! of the specified function. +!! +!! Example function: f(x) = exp(-x^2) * cos(2.0_dp * x) + +program example_monte_carlo + use monte_carlo_integration + implicit none + + real(dp) :: lower_bound, upper_bound, integral_result, error_estimate + integer :: random_samples_number + + ! Set the integration limits and number of random samples + lower_bound = -1.0_dp + upper_bound = 1.0_dp + random_samples_number = 1000000 !! 1E6 Number of random samples + + ! Call Monte Carlo integration with the function passed as an argument + call monte_carlo(integral_result, error_estimate, lower_bound, upper_bound, random_samples_number, function) + + write (*, '(A, F12.6, A, F12.6)') "Monte Carlo result: ", integral_result, " +- ", error_estimate !! ≈ 0.858421 + +contains + + function function(x) result(fx) + implicit none + real(dp), intent(in) :: x + real(dp) :: fx + + fx = exp(-x**2)*cos(2.0_dp*x) !! Example function to integrate + end function function + +end program example_monte_carlo diff --git a/examples/maths/numerical_integration/simpson.f90 b/examples/maths/numerical_integration/simpson.f90 new file mode 100644 index 0000000..be81758 --- /dev/null +++ b/examples/maths/numerical_integration/simpson.f90 @@ -0,0 +1,45 @@ +!> Example Program for Simpson's Rule +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #25 +!! https://github.com/TheAlgorithms/Fortran/pull/25 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! +!! This program demonstrates the use of Simpson's rule for numerical integration. +!! +!! It sets the integration limits and number of panels, and calls the +!! simpson subroutine to compute the approximate value of the definite integral +!! of the specified function. +!! +!! Example function: f(x) = exp(-x^2) * cos(2.0_dp * x) + +program example_simpson + use simpson_rule + implicit none + + real(dp) :: lower_bound, upper_bound, integral_result + integer :: panels_number + + ! Set the integration limits and number of panels + lower_bound = -1.0_dp + upper_bound = 1.0_dp + panels_number = 100 !! Number of subdivisions (must be even) + + ! Call Simpson's rule with the function passed as an argument + call simpson(integral_result, lower_bound, upper_bound, panels_number, function) + + write (*, '(A, F12.8)') "Simpson's rule yields: ", integral_result !! ≈ 0.85819555 + +contains + + function function(x) result(fx) + implicit none + real(dp), intent(in) :: x + real(dp) :: fx + + fx = exp(-x**2)*cos(2.0_dp*x) !! Example function to integrate + end function function + +end program example_simpson diff --git a/examples/maths/numerical_integration/trapezoid.f90 b/examples/maths/numerical_integration/trapezoid.f90 new file mode 100644 index 0000000..4be1ced --- /dev/null +++ b/examples/maths/numerical_integration/trapezoid.f90 @@ -0,0 +1,45 @@ +!> Example Program for Trapezoidal Rule +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #25 +!! https://github.com/TheAlgorithms/Fortran/pull/25 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! +!! This program demonstrates the use of the Trapezoidal rule for numerical integration. +!! +!! It sets the integration limits and number of panels, and calls the +!! trapezoid subroutine to compute the approximate value of the definite integral +!! of the specified function. +!! +!! Example function: f(x) = exp(-x^2) * cos(2.0_dp * x) + +program example_tapezoid + use trapezoidal_rule + implicit none + + real(dp) :: lower_bound, upper_bound, integral_result + integer :: panels_number + + ! Set the integration limits and number of panels + lower_bound = -1.0_dp + upper_bound = 1.0_dp + panels_number = 1000000 !! 1E6 Number of subdivisions + + ! Call the trapezoidal rule with the function passed as an argument + call trapezoid(integral_result, lower_bound, upper_bound, panels_number, function) + + write (*, '(A, F12.6)') 'Trapezoidal rule yields: ', integral_result !! ≈ 0.858195 + +contains + + function function(x) result(fx) + implicit none + real(dp), intent(in) :: x + real(dp) :: fx + + fx = exp(-x**2)*cos(2.0_dp*x) !! Example function to integrate + end function function + +end program example_tapezoid diff --git a/examples/sorts/example_usage_gnome_sort.f90 b/examples/sorts/example_usage_gnome_sort.f90 index 5c2cb15..67063e2 100644 --- a/examples/sorts/example_usage_gnome_sort.f90 +++ b/examples/sorts/example_usage_gnome_sort.f90 @@ -1,5 +1,12 @@ !> Test program for the Gnome Sort algorithm - +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #09 +!! https://github.com/TheAlgorithms/Fortran/pull/9 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! This program demonstrates the use of the gnome_sort_module by sorting an array of integers. program test_gnome_sort diff --git a/examples/sorts/example_usage_heap_sort.f90 b/examples/sorts/example_usage_heap_sort.f90 index 24c705f..a1ba0e5 100644 --- a/examples/sorts/example_usage_heap_sort.f90 +++ b/examples/sorts/example_usage_heap_sort.f90 @@ -1,5 +1,12 @@ !> Example program for the Heap Sort algorithm !! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #8 +!! https://github.com/TheAlgorithms/Fortran/pull/8 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! This program demonstrates the use of the heap_sort_module by sorting an array of integers. program test_heap_sort diff --git a/examples/sorts/example_usage_merge_sort.f90 b/examples/sorts/example_usage_merge_sort.f90 index 79893c3..a43c9a5 100644 --- a/examples/sorts/example_usage_merge_sort.f90 +++ b/examples/sorts/example_usage_merge_sort.f90 @@ -1,5 +1,12 @@ !> Test program for the Merge Sort algorithm - +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #7 +!! https://github.com/TheAlgorithms/Fortran/pull/7 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! This program demonstrates the use of the merge_sort_module by sorting an array of integers. program test_merge_sort diff --git a/examples/sorts/example_usage_quick_sort.f90 b/examples/sorts/example_usage_quick_sort.f90 index c61b6dd..c482918 100644 --- a/examples/sorts/example_usage_quick_sort.f90 +++ b/examples/sorts/example_usage_quick_sort.f90 @@ -1,4 +1,12 @@ !> Example program for the Quick Sort algorithm +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #10 +!! https://github.com/TheAlgorithms/Fortran/pull/10 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! This program demonstrates the use of the quick_sort_module by sorting an array of integers. program test_quick_sort diff --git a/examples/sorts/example_usage_radix_sort.f90 b/examples/sorts/example_usage_radix_sort.f90 index 811819a..86f1ae0 100644 --- a/examples/sorts/example_usage_radix_sort.f90 +++ b/examples/sorts/example_usage_radix_sort.f90 @@ -1,5 +1,12 @@ !> Test program for the Radix Sort algorithm - +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #11 +!! https://github.com/TheAlgorithms/Fortran/pull/11 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! This program demonstrates the use of the radix_sort_module by sorting an array of integers. !! The base parameter affects the internal digit processing but does not change the final sorted order !! of decimal integers. The output is always in decimal form. diff --git a/modules/maths/numerical_integration/gaussian_legendre.f90 b/modules/maths/numerical_integration/gaussian_legendre.f90 new file mode 100644 index 0000000..27599f9 --- /dev/null +++ b/modules/maths/numerical_integration/gaussian_legendre.f90 @@ -0,0 +1,107 @@ +!> Gaussian-Legendre Quadrature Module +!! +!! This module provides the implementation of Gaussian-Legendre Quadrature. +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #25 +!! https://github.com/TheAlgorithms/Fortran/pull/25 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! +!! The method approximates the definite integral of a function over a specified interval [a, b]. +!! +!! The quadrature method works by transforming nodes and weights from the reference interval [-1, 1] to the +!! interval [a, b] and then evaluating the function at these nodes. The integral is then approximated by summing +!! the product of function values and corresponding weights. +!! +!! Contents: +!! - `gauss_legendre_quadrature`: A subroutine to perform Gaussian-Legendre quadrature using provided nodes and weights. +!! - `gauss_legendre_weights`: A helper subroutine to initialize the quadrature nodes and weights for different orders (n). +!! +!! Input: +!! - `a`: Lower bound of integration (real(dp)) +!! - `b`: Upper bound of integration (real(dp)) +!! - `n`: Number of quadrature points (integer) +!! - `func`: The function to integrate (interface) +!! +!! Output: +!! - `integral_result`: Approximate value of the integral (real(dp)) + +module gaussian_legendre_quadrature + implicit none + integer, parameter :: dp = kind(1.0d0) !! Double precision parameter + +contains + + ! General Gaussian Quadrature for definite integral + subroutine gauss_legendre_quadrature(integral_result, a, b, n, func) + implicit none + real(dp), intent(out) :: integral_result + real(dp), intent(in) :: a, b + integer, intent(in) :: n !! Number of quadrature points (order of accuracy) + + real(dp), dimension(n) :: t, w, x + real(dp), dimension(:), allocatable :: fx + integer :: i + + ! Interface for the function + interface + real(kind(0.d0)) function func(x) result(fx) + real(kind(0.d0)), intent(in) :: x + end function func + end interface + + ! Initialize nodes and weights for Gauss-Legendre quadrature based on n + call gauss_legendre_weights(t, w, n) + + ! Allocate the function value array + allocate (fx(n)) + + ! Transform the nodes from the reference interval [-1, 1] to [a, b] + x = (b + a)/2.0_dp + (b - a)*t/2.0_dp + + ! Compute function values at the transformed points + do i = 1, n + fx(i) = func(x(i)) + end do + + ! Apply the Gaussian-Legendre quadrature formula + integral_result = sum(w*fx)*(b - a)/2.0_dp + + ! Deallocate fx array + deallocate (fx) + + end subroutine gauss_legendre_quadrature + + ! Subroutine to initialize Gauss-Legendre nodes and weights + subroutine gauss_legendre_weights(t, w, n) + implicit none + integer, intent(in) :: n + real(dp), intent(out), dimension(n) :: t, w !! Nodes (t) and weights (w) + + ! Predefined nodes and weights for different values of n + select case (n) + case (1) + t = [0.0_dp] !! Single node at the center for n = 1 + w = [2.0_dp] !! Weight of 2 for the single point + case (2) + t = [-0.5773502692_dp, 0.5773502692_dp] !! Symmetric nodes for n = 2 + w = [1.0_dp, 1.0_dp] !! Equal weights for n = 2 + case (3) + t = [-0.7745966692_dp, 0.0_dp, 0.7745966692_dp] !! Symmetric nodes for n = 3 + w = [0.5555555556_dp, 0.8888888889_dp, 0.5555555556_dp] !! Weights for n = 3 + case (4) + t = [-0.8611363116_dp, -0.3399810436_dp, 0.3399810436_dp, 0.8611363116_dp] !! Nodes for n = 4 + w = [0.3478548451_dp, 0.6521451549_dp, 0.6521451549_dp, 0.3478548451_dp] !! Weights for n = 4 + case (5) + t = [-0.9061798459_dp, -0.5384693101_dp, 0.0_dp, 0.5384693101_dp, 0.9061798459_dp] !! Nodes for n = 5 + w = [0.2369268851_dp, 0.4786286705_dp, 0.5688888889_dp, 0.4786286705_dp, 0.2369268851_dp] !! Weights for n = 5 + ! You can add more cases to support higher values of n. + case default + print *, 'Gauss-Legendre quadrature for n > 5 is not implemented.' + end select + + end subroutine gauss_legendre_weights + +end module gaussian_legendre_quadrature diff --git a/modules/maths/numerical_integration/midpoint.f90 b/modules/maths/numerical_integration/midpoint.f90 new file mode 100644 index 0000000..4f6589f --- /dev/null +++ b/modules/maths/numerical_integration/midpoint.f90 @@ -0,0 +1,72 @@ +!> Midpoint rule Module +!! +!! This module implements Midpoint rule for numerical integration. +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #25 +!! https://github.com/TheAlgorithms/Fortran/pull/25 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! +!! The midpoint rule approximates the integral by calculating the function +!! value at the midpoint of each subinterval and summing these values, multiplied +!! by the width of the subintervals. +!! +!! Note: This implementation is valid for one-dimensional functions +!! +!! Input: +!! - `a`: Lower bound of integration (real(dp)) +!! - `b`: Upper bound of integration (real(dp)) +!! - `n`: Number of panels (integer) +!! - `func`: The function to integrate (interface) +!! +!! Output: +!! - `integral_result`: Approximate value of the integral (real(dp)) + +module midpoint_rule + implicit none + integer, parameter :: dp = kind(0.d0) !! Double precision parameter + +contains + + subroutine midpoint(integral_result, a, b, n, func) + implicit none + integer, intent(in) :: n + real(dp), intent(in) :: a, b + real(dp), intent(out) :: integral_result + + real(dp), dimension(:), allocatable :: x, fx + real(dp) :: h + integer :: i + + ! Interface for the function + interface + real(kind(0.d0)) function func(x) + real(kind(0.d0)), intent(in) :: x + end function func + end interface + + ! Step size + h = (b - a)/real(n, dp) + + ! Allocate array for midpoints + allocate (x(1:n), fx(1:n)) + + ! Calculate midpoints + x = [(a + (real(i, dp) - 0.5_dp)*h, i=1, n)] + + ! Apply function to each midpoint + do i = 1, n + fx(i) = func(x(i)) + end do + + ! Final integral value + integral_result = h*sum(fx) + + ! Deallocate arrays + deallocate (x, fx) + + end subroutine midpoint + +end module midpoint_rule diff --git a/modules/maths/numerical_integration/monte_carlo.f90 b/modules/maths/numerical_integration/monte_carlo.f90 new file mode 100644 index 0000000..a649e7c --- /dev/null +++ b/modules/maths/numerical_integration/monte_carlo.f90 @@ -0,0 +1,83 @@ +!> Monte Carlo Integration Module +!! +!! This module estimates the integral of a function over a specified range +!! using the Monte Carlo method (with OpenMP parallelization) and provides an error estimate. +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #25 +!! https://github.com/TheAlgorithms/Fortran/pull/25 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! +!! The method works by randomly sampling points within the integration range [a, b] +!! and evaluating the function at those points to estimate the integral. +!! +!! Note: This implementation is valid for one-dimensional functions +!! +!! Input: +!! - `a`: Lower bound of integration (real(dp)) +!! - `b`: Upper bound of integration (real(dp)) +!! - `n`: Number of random samples (integer) +!! - `func`: The function to integrate (interface) +!! +!! Output: +!! - `integral_result`: Approximate value of the integral (real(dp)) +!! - `error_estimate`: Estimated error of the integral approximation (real(dp)) + +module monte_carlo_integration + use omp_lib !! OpenMP library for parallelization + implicit none + integer, parameter :: dp = kind(0.d0) !! Double precision parameter + +contains + + subroutine monte_carlo(integral_result, error_estimate, a, b, n, func) + implicit none + integer, intent(in) :: n + real(dp) :: n_dp !! Hold n as double precision + real(dp), intent(in) :: a, b + real(dp), intent(out) :: integral_result, error_estimate + + real(dp), dimension(:), allocatable :: uniform_sample, fx + real(dp) :: sum_fx, sum_fx_squared + integer :: i + + ! Interface for the function + interface + real(kind(0.d0)) function func(x) + real(kind(0.d0)), intent(in) :: x + end function func + end interface + + ! Allocate arrays for random samples and function values + allocate (uniform_sample(1:n), fx(1:n)) + + ! Generate uniform random points in [a, b] + call random_number(uniform_sample) + uniform_sample = a + (b - a)*uniform_sample !! Scale to the interval [a, b] + + ! Evaluate the function at all random points in parallel + !$omp parallel do !! OpenMP parallelization to distribute the loop across multiple threads + do i = 1, n + fx(i) = func(uniform_sample(i)) + end do + !$omp end parallel do + + ! Sum of function values and sum of function values squared (for error estimation) + sum_fx = sum(fx) + sum_fx_squared = sum(fx**2) + + ! Compute the Monte Carlo estimate of the integral + integral_result = (b - a)*(sum_fx/real(n, dp)) + + ! Estimate the error using the variance of the function values + n_dp = real(n, dp) + error_estimate = sqrt((sum_fx_squared/n_dp - (sum_fx/n_dp)**2)/(n_dp - 1))*(b - a) + + ! Deallocate arrays + deallocate (uniform_sample, fx) + + end subroutine monte_carlo + +end module monte_carlo_integration diff --git a/modules/maths/numerical_integration/simpson.f90 b/modules/maths/numerical_integration/simpson.f90 new file mode 100644 index 0000000..028abe0 --- /dev/null +++ b/modules/maths/numerical_integration/simpson.f90 @@ -0,0 +1,79 @@ +!> Simpson's Rule Module +!! +!! This module implements Simpson's rule for numerical integration. +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #25 +!! https://github.com/TheAlgorithms/Fortran/pull/25 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! +!! Simpson's rule approximates the definite integral of a function by +!! dividing the area under the curve into parabolic segments and summing +!! their areas, providing a higher degree of accuracy than the Trapezoidal rule. +!! +!! Note: This implementation is valid for one-dimensional functions +!! +!! Input: +!! - `a`: Lower bound of the integration (real(dp)) +!! - `b`: Upper bound of the integration (real(dp)) +!! - `n`: Number of panels (integer, must be even) +!! - `func`: The function to integrate (interface) +!! +!! Output: +!! - `integral_result`: Approximate value of the definite integral (real(dp)) +!! + +module simpson_rule + implicit none + integer, parameter :: dp = kind(0.d0) !! Double precision parameter + +contains + + ! Simpson's rule with function passed via interface + subroutine simpson(integral_result, a, b, n, func) + implicit none + integer, intent(in) :: n + real(dp), intent(in) :: a, b + real(dp), intent(out) :: integral_result + + real(dp), dimension(:), allocatable :: x, fx + real(dp) :: h + integer :: i + + ! Interface for the function + interface + real(kind(0.d0)) function func(x) + real(kind(0.d0)), intent(in) :: x + end function func + end interface + + ! Check if n is even + if (mod(n, 2) /= 0) then + write (*, *) 'Error: The number of panels (n) must be even.' + stop + end if + + ! Step size + h = (b - a)/real(n, dp) + + ! Allocate arrays + allocate (x(0:n), fx(0:n)) + + ! Create an array of x values, contains the endpoints and the midpoints. + x = [(a + (real(i, dp))*h, i=0, n)] + + ! Apply the function to each x value + do i = 0, n + fx(i) = func(x(i)) + end do + + ! Apply Simpson's rule using array slicing + integral_result = (fx(0) + fx(n) + 4.0_dp*sum(fx(1:n - 1:2)) + 2.0_dp*sum(fx(2:n - 2:2)))*(h/3.0_dp) + + ! Deallocate arrays + deallocate (x, fx) + end subroutine simpson + +end module simpson_rule diff --git a/modules/maths/numerical_integration/trapezoid.f90 b/modules/maths/numerical_integration/trapezoid.f90 new file mode 100644 index 0000000..955fb8b --- /dev/null +++ b/modules/maths/numerical_integration/trapezoid.f90 @@ -0,0 +1,72 @@ +!> Trapezoidal Rule Module +!! +!! This module implements the Trapezoidal rule for numerical integration. +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #25 +!! https://github.com/TheAlgorithms/Fortran/pull/25 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! +!! The Trapezoidal rule approximates the definite integral of a function by +!! dividing the area under the curve into trapezoids and summing their areas. +!! +!! Note: This implementation is valid for one-dimensional functions +!! +!! Input: +!! - `a`: Lower bound of the integration (real(dp)) +!! - `b`: Upper bound of the integration (real(dp)) +!! - `n`: Number of panels (integer) +!! - `func`: The function to integrate (interface) +!! +!! Output: +!! - `integral_result`: Approximate value of the definite integral (real(dp)) +!! + +module trapezoidal_rule + implicit none + integer, parameter :: dp = kind(0.d0) !! Double precision parameter + +contains + + ! Trapezoidal rule with function passed via interface + subroutine trapezoid(integral_result, a, b, n, func) + implicit none + integer, intent(in) :: n + real(dp), intent(in) :: a, b + real(dp), intent(out) :: integral_result + + real(dp), dimension(:), allocatable :: x, fx + real(dp) :: h + integer :: i + + ! Interface for the function + interface + real(kind(0.d0)) function func(x) + real(kind(0.d0)), intent(in) :: x + end function func + end interface + + ! Step size + h = (b - a)/real(n, dp) + + ! Allocate arrays + allocate (x(0:n), fx(0:n)) + + ! Create an array of x values + x = [(a + (real(i, dp))*h, i=0, n)] + + ! Apply the function to each x value + do i = 0, n + fx(i) = func(x(i)) + end do + + ! Apply trapezoidal rule using array slicing + integral_result = ((fx(0) + fx(n))*0.5_dp + sum(fx(1:n)))*h + + ! Deallocate arrays + deallocate (x, fx) + end subroutine trapezoid + +end module trapezoidal_rule diff --git a/modules/sorts/gnome_sort.f90 b/modules/sorts/gnome_sort.f90 index b92e912..b89c773 100644 --- a/modules/sorts/gnome_sort.f90 +++ b/modules/sorts/gnome_sort.f90 @@ -1,6 +1,13 @@ !> Gnome Sort Algorithm - -!> This module implements the Gnome Sort algorithm. +!! +!! This module implements the Gnome Sort algorithm. +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #09 +!! https://github.com/TheAlgorithms/Fortran/pull/9 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! !! !! Gnome Sort is a simple comparison-based sorting algorithm. !! It iterates through the array, comparing and swapping elements if needed. @@ -12,6 +19,7 @@ !! !! Output: !! - A sorted array of integers. +!! module gnome_sort_module implicit none diff --git a/modules/sorts/heap_sort.f90 b/modules/sorts/heap_sort.f90 index 46b05d5..40f63b1 100644 --- a/modules/sorts/heap_sort.f90 +++ b/modules/sorts/heap_sort.f90 @@ -1,7 +1,14 @@ -!> ## Heap Sort Algorithm -!> +!> Heap Sort Algorithm +!! !! This module implements the Heap Sort algorithm. !! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #8 +!! https://github.com/TheAlgorithms/Fortran/pull/8 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! Heap Sort is a comparison-based sorting algorithm that uses a binary heap data structure. !! It first builds a max heap from the input data and then repeatedly extracts the maximum !! element from the heap and reconstructs the heap until the array is sorted. @@ -13,6 +20,7 @@ !! !! Output: !! - A sorted array of integers. +!! module heap_sort_module implicit none diff --git a/modules/sorts/merge_sort.f90 b/modules/sorts/merge_sort.f90 index 95971ec..a754efd 100644 --- a/modules/sorts/merge_sort.f90 +++ b/modules/sorts/merge_sort.f90 @@ -1,6 +1,13 @@ !> Merge Sort Algorithm - -!> This module implements the Merge Sort algorithm. +!! +!! This module implements the Merge Sort algorithm. +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #7 +!! https://github.com/TheAlgorithms/Fortran/pull/7 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! !! !! Merge Sort is a divide-and-conquer algorithm. It divides the input array into two halves, recursively sorts them, !! and then merges the two sorted halves. diff --git a/modules/sorts/quick_sort.f90 b/modules/sorts/quick_sort.f90 index fa1bbd4..0c5839f 100644 --- a/modules/sorts/quick_sort.f90 +++ b/modules/sorts/quick_sort.f90 @@ -1,7 +1,15 @@ !> Quick Sort Algorithm +!! !! This module implements the Quick Sort algorithm, a highly efficient !! sorting technique that uses the divide-and-conquer strategy. !! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #10 +!! https://github.com/TheAlgorithms/Fortran/pull/10 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! Quick Sort works by selecting a pivot element and partitioning the !! array into elements less than the pivot and elements greater than the pivot. !! diff --git a/modules/sorts/radix_sort.f90 b/modules/sorts/radix_sort.f90 index 64fbeb6..79a72de 100644 --- a/modules/sorts/radix_sort.f90 +++ b/modules/sorts/radix_sort.f90 @@ -1,6 +1,13 @@ !> Radix Sort Algorithm - -!> This module implements the Radix Sort algorithm with configurable base. +!! +!! This module implements the Radix Sort algorithm with configurable base. +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #11 +!! https://github.com/TheAlgorithms/Fortran/pull/11 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! !! !! Radix Sort is a non-comparison-based sorting algorithm that sorts numbers by processing individual digits. !! It is particularly efficient for sorting large lists of integers with a fixed number of digits. @@ -13,6 +20,7 @@ !! !! Output: !! - A sorted array of integers. +!! module radix_sort_module implicit none diff --git a/tests/sorts/tests_gnome_sort.f90 b/tests/sorts/tests_gnome_sort.f90 index 04ad524..d921c67 100644 --- a/tests/sorts/tests_gnome_sort.f90 +++ b/tests/sorts/tests_gnome_sort.f90 @@ -1,5 +1,12 @@ !> Test program for the Gnome Sort algorithm - +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #09 +!! https://github.com/TheAlgorithms/Fortran/pull/9 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! This program provides additional test cases to validate the gnome_sort_module. program tests_gnome_sort diff --git a/tests/sorts/tests_heap_sort.f90 b/tests/sorts/tests_heap_sort.f90 index 0b28b2a..18b2794 100644 --- a/tests/sorts/tests_heap_sort.f90 +++ b/tests/sorts/tests_heap_sort.f90 @@ -1,5 +1,12 @@ !> Test program for the Heap Sort algorithm - +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #8 +!! https://github.com/TheAlgorithms/Fortran/pull/8 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! This program provides additional test cases to validate the heap_sort_module. program tests_heap_sort diff --git a/tests/sorts/tests_merge_sort.f90 b/tests/sorts/tests_merge_sort.f90 index a55ef6c..5da8ad0 100644 --- a/tests/sorts/tests_merge_sort.f90 +++ b/tests/sorts/tests_merge_sort.f90 @@ -1,5 +1,12 @@ !> Test program for the Merge Sort algorithm - +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #7 +!! https://github.com/TheAlgorithms/Fortran/pull/7 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! This program provides additional test cases to validate the merge_sort_module. program tests_merge_sort diff --git a/tests/sorts/tests_quick_sort.f90 b/tests/sorts/tests_quick_sort.f90 index 547970a..a46835f 100644 --- a/tests/sorts/tests_quick_sort.f90 +++ b/tests/sorts/tests_quick_sort.f90 @@ -1,5 +1,12 @@ !> Test program for the Quick Sort algorithm - +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #10 +!! https://github.com/TheAlgorithms/Fortran/pull/10 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! This program provides additional test cases to validate the quick_sort_module. program tests_quick_sort diff --git a/tests/sorts/tests_radix_sort.f90 b/tests/sorts/tests_radix_sort.f90 index 22c04a2..056fd5c 100644 --- a/tests/sorts/tests_radix_sort.f90 +++ b/tests/sorts/tests_radix_sort.f90 @@ -1,5 +1,12 @@ !> Test program for the Radix Sort algorithm - +!! +!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) +!! in Pull Request: #11 +!! https://github.com/TheAlgorithms/Fortran/pull/11 +!! +!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request +!! addressing bugs/corrections to this file. Thank you! +!! !! This program provides additional test cases to validate the radix_sort_module. !! The radix (base) parameter affects the internal digit processing for sorting, but the final output is always in decimal form.