Section Computing Pi: Compute Pi#
Adapted from: gjbex/Fortran-MOOC
This program demonstrates computing \(\pi\) in Fortran by using the following equation:#
\[
\Large \pi = 4 \int_{0}^{1} \sqrt{1-x^2}dx
\]
In file section_computing_pi_compute_pi.f90#
program compute_pi
use, intrinsic :: iso_fortran_env, only : DP => REAL64, I8 => INT64
implicit none
integer(kind=I8) :: i, nr_iters
real(kind=DP) :: delta, x, pi_val
real(kind=DP) :: pi_val_actual
pi_val = 0.0_DP
pi_val_actual = 2.0_DP * acos(0.0_DP)
nr_iters = get_nr_iters()
delta = 1.0_DP/nr_iters
x = 0.0_DP
do i = 1, nr_iters
pi_val = pi_val + sqrt(1.0_DP - x**2)
x = x + delta
end do
pi_val = 4.0_DP*pi_val/nr_iters
print '(A, I10, A, F25.15)', "After ", nr_iters, " loops, Pi = ", pi_val
print '(A, F25.15)', "Actual value of Pi = ", pi_val_actual
print '(A, F25.15)', "Absolute difference = ", abs(pi_val - pi_val_actual)
contains
function get_nr_iters() result(nr_iters)
use, intrinsic :: iso_fortran_env, only : error_unit
implicit none
integer(kind=I8) :: nr_iters
integer(kind=I8), parameter :: default_nr_iters = 1000_I8
character(len=1024) :: buffer, msg
integer :: istat
if (command_argument_count() >= 1) then
call get_command_argument(1, buffer)
read (buffer, fmt=*, iostat=istat, iomsg=msg) nr_iters
if (istat /= 0) then
write (unit=error_unit, fmt='(2A)') &
'error: ', msg
stop 1
end if
else
nr_iters = default_nr_iters
end if
end function get_nr_iters
end program compute_pi
The above program is compiled and run using Fortran Package Manager (fpm):
Build the Program using FPM (Fortran Package Manager)#
import os
root_dir = ""
root_dir = os.getcwd()
The following configuration file (fpm.toml) was used:
name = "Section_Computing_Pi_Compute_Pi"
[build]
auto-executables = true
auto-tests = true
auto-examples = true
[install]
library = false
[[executable]]
name="Section_Computing_Pi_Compute_Pi"
source-dir="app"
main="section_computing_pi_compute_pi.f90"
code_dir = root_dir + "/" + "Fortran_Code/Section_Computing_Pi_Compute_Pi"
os.chdir(code_dir)
build_status = os.system("fpm build 2>/dev/null")
Run the Program using FPM (Fortran Package Manager)#
10 Iterations#
%%timeit -r 10 -n 1
exec_status = os.system("fpm run -- 10 2>/dev/null > output.txt")
43.7 ms ± 4.15 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
%cat output.txt
After 10 loops, Pi = 3.304518326248318
Actual value of Pi = 3.141592653589793
Absolute difference = 0.162925672658525
100 Iterations#
%%timeit -r 10 -n 1
exec_status = os.system("fpm run -- 100 2>/dev/null > output.txt")
42.2 ms ± 5.83 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
%cat output.txt
After 100 loops, Pi = 3.160417031779042
Actual value of Pi = 3.141592653589793
Absolute difference = 0.018824378189249
1,000 Iterations#
%%timeit -r 10 -n 1
exec_status = os.system("fpm run -- 1000 2>/dev/null > output.txt")
45.3 ms ± 4.54 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
%cat output.txt
After 1000 loops, Pi = 3.143555466911022
Actual value of Pi = 3.141592653589793
Absolute difference = 0.001962813321229
10,000 Iterations#
%%timeit -r 10 -n 1
exec_status = os.system("fpm run -- 10000 2>/dev/null > output.txt")
51.2 ms ± 21.8 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
%cat output.txt
After 10000 loops, Pi = 3.141791477611602
Actual value of Pi = 3.141592653589793
Absolute difference = 0.000198824021809
100,000 Iterations#
%%timeit -r 10 -n 1
exec_status = os.system("fpm run -- 100000 2>/dev/null > output.txt")
The slowest run took 4.78 times longer than the fastest. This could mean that an intermediate result is being cached.
66.7 ms ± 48.1 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
%cat output.txt
After 100000 loops, Pi = 3.141612616406209
Actual value of Pi = 3.141592653589793
Absolute difference = 0.000019962816416
1,000,000 Iterations#
%%timeit -r 10 -n 1
exec_status = os.system("fpm run -- 1000000 2>/dev/null > output.txt")
51.1 ms ± 14.8 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
%cat output.txt
After 1000000 loops, Pi = 3.141594652402481
Actual value of Pi = 3.141592653589793
Absolute difference = 0.000001998812688
10,000,000 Iterations#
%%timeit -r 10 -n 1
exec_status = os.system("fpm run -- 10000000 2>/dev/null > output.txt")
68.9 ms ± 11.1 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
%cat output.txt
After 10000000 loops, Pi = 3.141592854147901
Actual value of Pi = 3.141592653589793
Absolute difference = 0.000000200558108
100,000,000 Iterations#
%%timeit -r 10 -n 1
exec_status = os.system("fpm run -- 100000000 2>/dev/null > output.txt")
304 ms ± 16 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
%cat output.txt
After 100000000 loops, Pi = 3.141592668260093
Actual value of Pi = 3.141592653589793
Absolute difference = 0.000000014670300
1,000,000,000 Iterations#
%%timeit -r 10 -n 1
exec_status = os.system("fpm run -- 1000000000 2>/dev/null > output.txt")
2.64 s ± 135 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
%cat output.txt
After 1000000000 loops, Pi = 3.141592665675041
Actual value of Pi = 3.141592653589793
Absolute difference = 0.000000012085248