MODULE space_data
REAL :: a, b, c, upper, lower
INTEGER :: n
END MODULE
program riemann
USE space_data
IMPLICIT NONE
INTEGER :: i, l
CHARACTER :: choice, m, t, q, yn
REAL :: mid, sum, trap_area
WRITE(*,*) ' COP 2271 - Project 3'
WRITE(*,*) ' Integration Approximation Methods '
WRITE(*,*) '-----------------------------------------'
WRITE(*,*) ' '
a = 0
b = 0
c = 0
n = 0
DO
WRITE(*,*) 'Choose a method: '
WRITE(*,*) ' M) Riemann "Middle" Rule '
WRITE(*,*) ' T) Riemann "Trapezoidal" Rule'
WRITE(*,*) ' Q) Quit '
WRITE(*,'(A,\)') 'Choice? '
READ(*,*) choice
IF (choice == 'Q' .OR. choice == 'q') THEN
WRITE(*,*) ' '
STOP
END IF
IF (choice /= 'M' .AND. choice /= 'm' .AND. choice /= 'T' .AND. choice /= 't' .AND. choice /= 'Q' .AND. choice /= 'q') THEN
WRITE(*,*) '===================================='
WRITE(*,*) ' Invalid input. Must be M, T, or Q.'
WRITE(*,*) '===================================='
WRITE(*,*) ' '
END IF
IF (choice == 'M' .OR. choice == 'm' .OR. choice == 'T' .OR. choice == 't') THEN
IF (n > 0) THEN
DO
WRITE(*,*) ' '
WRITE(*,'(A,\)') ' Would you like to reenter A, B, C, and the interval over which to integrate (y/n)? '
READ(*,*) yn
IF ( yn /= 'Y' .AND. yn /= 'y' .AND. yn /= 'N' .AND. yn /= 'n') THEN
WRITE(*,*) ' '
WRITE(*,*) '==================================='
WRITE(*,*) ' Invalid input. Must be Y or N. '
WRITE(*,*) '==================================='
ELSE
EXIT
END IF
END DO
SELECT CASE(yn)
CASE('Y','y')
CALL choi_mod(choice, m, t, q)
CASE('N','n')
IF (choice == 'm' .OR. choice == 'M') THEN
CALL rite(a, b, c, lower, upper)
CALL midsum(upper, lower, a, b, c, i, n)
ELSE IF (choice == 't' .OR. choice == 'T') THEN
WRITE(*,*) 'Using Riemann "Trapazoidal" Rule to evaluate'
WRITE(*,*) 'y = ',a,'* x^2 +',b,'* x +', c
WRITE(*,*) 'from [',lower,',',upper,'].'
WRITE(*,*) ' '
WRITE(*,*) '# of intervals | Approximate area'
WRITE(*,*) '-----------------------------------'
CALL atrap(i)
ELSE
STOP
END IF
END SELECT
ELSE IF ( a == 0. .AND. b == 0. .AND. c == 0.) THEN
CALL choi(choice, m, t, q)
END IF
END IF
END DO
end program riemann
SUBROUTINE midsum(upper, lower, a, b, c, i, n)
IMPLICIT NONE
REAL, INTENT(IN) :: upper, lower, a, b, c
INTEGER :: i
INTEGER, INTENT(IN) :: n
REAL :: f_x, x_par
REAL :: delta_x, sum
INTEGER :: j
DO j = 1, n
sum = 0
x_par = 0
f_x = 0
delta_x = (upper - lower)/(2**j)
x_par = lower + .5*delta_x
f_x = a*((x_par)**2) + b*(x_par) + c
sum = delta_x*f_x
DO i = 2, (2**j)
x_par = delta_x + x_par
f_x = a*((x_par)**2) + b*(x_par) + c
sum = sum + (delta_x*f_x)
END DO
WRITE(*,'(A, I2, A, I7, A, A, f16.3)') ' 2^',j,' = ',2**j,' |', ' ', sum
WRITE(*,*) '---------------------------------'
END DO
WRITE(*,*) ' '
END SUBROUTINE midsum
SUBROUTINE rite(a, b, c, lower, upper)
IMPLICIT NONE
REAL, INTENT(IN) :: a, b, c, lower, upper
WRITE(*,*) 'Using Riemann "Middle" Rule to evaluate'
WRITE(*,*) 'y =',a,'* x^2 +',b,'* x +', c
WRITE(*,*) 'from [',lower,',',upper,'].'
WRITE(*,*) ' '
WRITE(*,*) '# of intervals | Approximate area'
WRITE(*,*) '---------------------------------'
END SUBROUTINE RITE
SUBROUTINE data()
USE space_data
IMPLICIT NONE
WRITE(*,*) ' '
WRITE(*,*) 'Enter A, B, and C for the quadratic formula to integrate in the form of:'
WRITE(*,*) 'y = Ax^2 + Bx + C'
WRITE(*,*) ' '
WRITE(*,'(A,\)') ' Enter A: '
READ(*,*) a
WRITE(*,'(A,\)') ' Enter B: '
READ(*,*) b
WRITE(*,'(A,\)') ' Enter C: '
READ(*,*) c
WRITE(*,*) ' '
DO
WRITE(*,'(A,\)') ' Enter minimum of integration range: '
READ (*,*) lower
WRITE(*,'(A,\)') ' Enter maximum of integration range: '
READ (*,*) upper
WRITE(*,*) ' '
IF (lower < upper) THEN
EXIT
ELSE
WRITE(*,*) '==================================='
WRITE(*,*) ' Invalid input. Max must be > Min. '
WRITE(*,*) '==================================='
WRITE(*,*) ' '
END IF
END DO
DO
WRITE(*,*) 'Enter number of approximations to examine'
WRITE(*,*) '(ex., entering 3 calculates the integral three times using'
WRITE(*,'(A,\)') ' 2^1, 2^2 and 2^3 intervals respectively): '
READ(*,*) n
IF (n <= 0.) THEN
WRITE(*,*) '==================================='
WRITE(*,*) ' Invalid input. Number must be > 0. '
WRITE(*,*) '==================================='
ELSE
EXIT
END IF
END DO
END SUBROUTINE data
SUBROUTINE choi(choice, m, t, q)
USE space_data
IMPLICIT NONE
CHARACTER :: choice, m, t, q
INTEGER :: i
SELECT CASE (choice)
CASE('M','m')
CALL data()
CALL rite(a, b, c, lower, upper)
CALL midsum(upper, lower, a, b, c, i, n)
CASE('T','t')
CALL data()
WRITE(*,*) 'Using Riemann "Trapazoidal" Rule to evaluate'
WRITE(*,*) 'y = ',a,'* x^2 +',b,'* x +', c
WRITE(*,*) 'from [',lower,',',upper,'].'
WRITE(*,*) '# of intervals | Approximate area'
WRITE(*,*) '---------------------------------'
CALL atrap(i)
CASE('Q','q')
WRITE(*,*) ' '
STOP
END SELECT
END SUBROUTINE choi
SUBROUTINE atrap(i)
USE space_data
IMPLICIT NONE
INTEGER :: i, j
REAL :: f_b1, f_b2, f_x1, f_x2, trap_area
REAL :: delta_x
DO j = 1, n
delta_x = (upper - lower)/(2**j)
trap_area = 0
DO i = 1, (2**j)
f_b1 = lower + delta_x*(i-1)
f_b2 = lower + delta_x*i
f_x1 = a*((f_b1)**2) + b*(f_b1) + c
f_x2 = a*((f_b2)**2) + b*(f_b2) + c
trap_area = trap_area + .5*delta_x*(f_x1 + f_x2)
END DO
WRITE(*,'(A, I2, A, I7, A, A, f16.3)') ' 2^',j,' = ',2**j,' |', ' ', trap_area
WRITE(*,*) '---------------------------------'
END DO
WRITE(*,*) ' '
END SUBROUTINE atrap
SUBROUTINE choi_mod(choice, m, t, q)
USE space_data
IMPLICIT NONE
CHARACTER :: choice, m, t, q
INTEGER :: i
SELECT CASE (choice)
CASE('M','m')
CALL data_mod()
CALL rite(a, b, c, lower, upper)
CALL midsum(upper, lower, a, b, c, i, n)
CASE('T','t')
CALL data_mod()
WRITE(*,*) 'Using Riemann "Trapazoidal" Rule to evaluate'
WRITE(*,*) 'y = ',a,'* x^2 +',b,'* x +', c
WRITE(*,*) 'from [',lower,',',upper,'].'
WRITE(*,*) '# of intervals | Approximate area'
WRITE(*,*) '---------------------------------'
CALL atrap(i)
CASE('Q','q')
WRITE(*,*) ' '
STOP
END SELECT
END SUBROUTINE choi_mod
SUBROUTINE data_mod()
USE space_data
IMPLICIT NONE
WRITE(*,*) ' '
WRITE(*,'(A,\)') ' Enter A: '
READ(*,*) a
WRITE(*,'(A,\)') ' Enter B: '
READ(*,*) b
WRITE(*,'(A,\)') ' Enter C: '
READ(*,*) c
WRITE(*,*) ' '
DO
WRITE(*,'(A,\)') ' Enter minimum of integration range: '
READ (*,*) lower
WRITE(*,'(A,\)') ' Enter maximum of integration range: '
READ (*,*) upper
WRITE(*,*) ' '
IF (lower < upper) THEN
EXIT
ELSE
WRITE(*,*) '==================================='
WRITE(*,*) ' Invalid input. Max must be > Min. '
WRITE(*,*) '==================================='
WRITE(*,*) ' '
END IF
END DO
DO
WRITE(*,*) 'Enter number of approximations to examine'
WRITE(*,*) '(ex., entering 3 calculates the integral three times using'
WRITE(*,'(A,\)') ' 2^1, 2^2 and 2^3 intervals respectively): '
READ(*,*) n
IF (n <= 0.) THEN
WRITE(*,*) '==================================='
WRITE(*,*) ' Invalid input. Number must be > 0. '
WRITE(*,*) '==================================='
ELSE
EXIT
END IF
END DO
END SUBROUTINE data_mod