From c9d03a4f4fc474ee5939b1f98f81315b7eb7febd Mon Sep 17 00:00:00 2001 From: colorizer Date: Sun, 10 Oct 2021 01:48:59 +0530 Subject: [PATCH 1/2] Implemented few math algorithms Implemented: 1. binomial_coefficient 2. Euclid gcd 3. Factorial 4. fibonacci 5. Gauss elimination 6. Pascal's triangle --- algorithms/math/binomial_coefficient.f90 | 17 ++++++ algorithms/math/euclid_gcd.f90 | 35 +++++++++++ algorithms/math/factorial_recursive.f90 | 23 ++++++++ algorithms/math/fibonacci.f90 | 48 +++++++++++++++ algorithms/math/gauss_elimination.f90 | 75 ++++++++++++++++++++++++ algorithms/math/pascals_triangle.f90 | 23 ++++++++ 6 files changed, 221 insertions(+) create mode 100644 algorithms/math/binomial_coefficient.f90 create mode 100644 algorithms/math/euclid_gcd.f90 create mode 100644 algorithms/math/factorial_recursive.f90 create mode 100644 algorithms/math/fibonacci.f90 create mode 100644 algorithms/math/gauss_elimination.f90 create mode 100644 algorithms/math/pascals_triangle.f90 diff --git a/algorithms/math/binomial_coefficient.f90 b/algorithms/math/binomial_coefficient.f90 new file mode 100644 index 0000000..660ff3e --- /dev/null +++ b/algorithms/math/binomial_coefficient.f90 @@ -0,0 +1,17 @@ +! To run the program using the gnu compiler, run the following +! gfortran -o binomial_coefficient binomial_coefficient.f90 +! ./binomial_coefficient +program binomialcoeff + implicit none + integer :: n, k, b, i ! Pass by value; not reference + + write(*, '(a)', advance='no') "Enter n, k : " + read (*,*) n, k + + b = 1 + do i = 1, k + b = b * (n-i+1) / i + end do + write(*, "('The binomial coefficient of (',(i0),',',(i0),') is: ', (i0))") n, k, b + +end program binomialcoeff diff --git a/algorithms/math/euclid_gcd.f90 b/algorithms/math/euclid_gcd.f90 new file mode 100644 index 0000000..ec0096c --- /dev/null +++ b/algorithms/math/euclid_gcd.f90 @@ -0,0 +1,35 @@ +! To run the program using the gnu compiler, run the following +! gfortran -o euclid_gcd euclid_gcd.f90 +! ./euclid_gcd +program euclid_gcd + use, intrinsic :: iso_fortran_env, only : input_unit, error_unit + implicit none + integer :: a, b, val, istat + character(len=1024) :: msg + + print *, "Enter the two numbers (+ve integers): " + ! The following model of reading input is not necessary. + ! ---------- + read(unit=input_unit, fmt=*, iostat=istat, iomsg=msg) a, b + if (istat /= 0) then + write(error_unit, fmt='(2A)') 'error: ', trim(msg) + stop 1 + end if + ! ---------- + ! Above section can be replaced with following if error handling is not required. + ! read *, a, b + val = gcd(a, b) + print *, 'The greatest common divisor is: ', val + + contains + function gcd(a,b) result(val) + integer, value :: a, b + integer :: t, val + do while (b /= 0) + t = b + b = mod(a, b) + a = t + end do + val = a + end function gcd +end program euclid_gcd diff --git a/algorithms/math/factorial_recursive.f90 b/algorithms/math/factorial_recursive.f90 new file mode 100644 index 0000000..8edb8dd --- /dev/null +++ b/algorithms/math/factorial_recursive.f90 @@ -0,0 +1,23 @@ +! To run the program using the gnu compiler, run the following +! gfortran -o factorial_recursive factorial_recursive.f90 +! ./factorial_recursive +program factorial_recursive + implicit none + integer :: n, f + + print *, 'Enter an integer n to compute its factorial: ' + read *, n + f = factorial(n) + print '((i0),"! = ",(i0))', n, f + + contains + recursive function factorial(n) result(f) + integer, intent(in) :: n + integer :: f + if (n <= 0) then + f = 1 + else + f = n * factorial(n - 1) + end if + end function factorial +end program factorial_recursive diff --git a/algorithms/math/fibonacci.f90 b/algorithms/math/fibonacci.f90 new file mode 100644 index 0000000..c8662ae --- /dev/null +++ b/algorithms/math/fibonacci.f90 @@ -0,0 +1,48 @@ +! To run the program using the gnu compiler, run the following +! gfortran -o fibonacci fibonacci.f90 +! ./fibonacci +program fibonacci + ! i8 -> double precision integers + ! error_unit -> used for writing error statements + use, intrinsic :: iso_fortran_env, only : i8=>int64, error_unit + implicit none ! an artifact from Fortran 77 + integer :: n + + print *, 'Enter a number: ' + read *, n + if (n <=0) then + write(error_unit, *) 'n must be a positive integer' + stop 1 + end if + print *, 'The fibonacci number for the specified position is' + print *, 'Recursive solution: ', fib_rec(n) + print *, 'Iterative solution: ', fib_itr(n) + + contains + ! Recursive solution + recursive function fib_rec(n) result(f) + integer, intent(in), value :: n + integer(i8) :: f + if (n<=1) then + f = 1 + return + else + f = fib_rec(n-1) + fib_rec(n-2) + end if + end function fib_rec + + ! Iterative solution + function fib_itr(n) result(f) ! iterative + integer,intent(in) :: n + integer(i8) :: f, tmp, f_1 + integer :: i + f_1 = 1 ! Initialization in separate line is necessary. Checkout following discussion + f = f_1 ! https://fortran-lang.discourse.group/t/fortran-function-remembers-values-newbie-help/2018 + + do i = 2, n + tmp=f + f = f + f_1 + f_1 = tmp + end do + end function fib_itr +end program fibonacci diff --git a/algorithms/math/gauss_elimination.f90 b/algorithms/math/gauss_elimination.f90 new file mode 100644 index 0000000..92ea031 --- /dev/null +++ b/algorithms/math/gauss_elimination.f90 @@ -0,0 +1,75 @@ +! Solves linear eqns: Ax = b for x. +program gauss_elimination + use, intrinsic :: iso_fortran_env, only : dp=>real64, error_unit, input_unit + implicit none + integer :: i, j, k, n, pos, istat ! n - Number of unknowns + real(dp), allocatable :: ag(:,:), x(:) ! Augumented matrix and solution vector + real(dp) :: factor + character(len=1024) :: msg ! string for holding error messages + + write(*, '(a)', advance='no') "Number of unknowns: " + read (input_unit, *, iostat=istat) n + if (istat /= 0) stop 1 + + allocate(ag(n, n+1)) + allocate(x(n)) + + call get_aug_matrix(ag) + + ! Forward elimination + do k = 1, n-1 + ! Partial scaled pivoting + pos = maxloc( abs(ag(k:n, k)/maxval(ag(k:n, :), dim=2)), dim=1 ) + j = k + pos - 1 + if (.not. j == k) call swap(ag(j,:), ag(k,:)) + ! Elimination + do i = k+1, n + factor = ag(i,k) / ag(k,k) + ag(i, k:) = ag(i, k:) - factor*ag(k, k:) + end do + end do + + ! Back substitution + x(n) = ag(n, n+1) / ag(n,n) + do i = n-1, 1, -1 + x(i) = ( ag(i,n+1) - dot_product(ag(i, i+1:n), x(i+1:n)) ) / ag(i,i) + end do + + print *, 'The solution vector x is: ' + print *, x + + deallocate(ag) + deallocate(x) + + contains + + ! Subroutine to get the values of the Augumented Matrix + subroutine get_aug_matrix(a) + ! Note that read statements below make use of istat and msg from parent program + real(dp), intent(inout) :: a(:,:) + integer :: n + n = size(a,1) + print *, 'Enter the Coefficient Matrix A (Row-wise) ' + do i = 1, n + write(*, '("A(",i0,", :) ")', advance='no') i + read (input_unit, *, iostat=istat, iomsg=msg) a(i,1:n) + if (istat /= 0) stop trim(msg) + end do + print *, 'Enter the RHS constants vector (b): ' + do i = 1, n + write(*, '("b(",i0,") ")', advance='no') i + read (input_unit, *, iostat=istat, iomsg=msg) a(i,n+1) + if (istat /= 0) stop trim(msg) + end do + end subroutine get_aug_matrix + + ! Subroutine to swap rows of the matrix + elemental subroutine swap(a, b) + real(dp), intent(inout) :: a, b + real(dp) :: temp + temp = a + a = b + b = temp + end subroutine swap + +end program gauss_elimination diff --git a/algorithms/math/pascals_triangle.f90 b/algorithms/math/pascals_triangle.f90 new file mode 100644 index 0000000..92a1eaf --- /dev/null +++ b/algorithms/math/pascals_triangle.f90 @@ -0,0 +1,23 @@ +! Solution based from https://stackoverflow.com/questions/22844838/pascal-triangle-in-fortran +! To run the program using the gnu compiler, run the following +! gfortran -o pascals_triangle pascals_triangle.f90 +! ./pascals_triangle +program pascals_triangle + implicit none + integer :: i, j, k, n, p + + write (*, "(A)", advance='no') 'Please enter number of lines n: ' + read (*, *) n + + do i=0,n-1 + p = 1 + do j=1,n-1-i + write(*, '(3X)', advance='no') ! write the leading spaces + end do + do k = 0, i + write(*, '(i6)', advance='no') p ! max length of integer value is 6 + p = p*(i-k)/(k+1) ! Binomial coefficient B(i, k) + end do + write(*, *) ! write a newline character + end do +end program pascals_triangle From 0593a0954c1ffc1e3296e54703edf018c73d5c50 Mon Sep 17 00:00:00 2001 From: colorizer Date: Sun, 10 Oct 2021 01:51:15 +0530 Subject: [PATCH 2/2] Added git ignore for directory files --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..727bc05 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.directory