Skip to content

Implemented few math Algorithms #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.directory
17 changes: 17 additions & 0 deletions algorithms/math/binomial_coefficient.f90
Original file line number Diff line number Diff line change
@@ -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
35 changes: 35 additions & 0 deletions algorithms/math/euclid_gcd.f90
Original file line number Diff line number Diff line change
@@ -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
23 changes: 23 additions & 0 deletions algorithms/math/factorial_recursive.f90
Original file line number Diff line number Diff line change
@@ -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
48 changes: 48 additions & 0 deletions algorithms/math/fibonacci.f90
Original file line number Diff line number Diff line change
@@ -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
75 changes: 75 additions & 0 deletions algorithms/math/gauss_elimination.f90
Original file line number Diff line number Diff line change
@@ -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
23 changes: 23 additions & 0 deletions algorithms/math/pascals_triangle.f90
Original file line number Diff line number Diff line change
@@ -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