Program series_main
  Implicit None
  Real, External :: series_sum
  Real, External :: arith_next, geom_next, power_next, sine_next
  Real :: init, x1, x2, ans
  Integer :: nterms
  Character (Len = 1) :: which
  Do
   Write (*,*) 'Choose one of the foll. &
        &  a (Arithmetic), g (Geometric), p (Power),  &
        &  s (Sine), q (quit)->'
   Read (*,*) which
   If (which == "q") EXIT
   Select Case (which)
      Case ("a")
         Call get_vals(init, nterms, x1, 'First term', &
              &    'Number of Terms', 'Increment')
         ans = series_sum(init, arith_next, nterms, x1)
         Write (*,*) 'The sum is: ', ans
      Case ("g")
         Call get_vals(init, nterms, x1, 'First term', &
              &    'Number of Terms', 'Multiplicative Factor')
         ans = series_sum(init, geom_next, nterms, x1)
         Write (*,*) 'The sum is: ', ans
      Case ("p")
         Call get_vals(init, nterms, x1, 'First term', &
              &    'Number of Terms', 'Power')
         ans = series_sum(init, power_next, nterms, x1)
         Write (*,*) 'The sum is: ', ans
      Case Default
         Cycle
      End Select
   End Do
End Program series_main

Subroutine get_vals(v1, v2, v3, s1, s2, s3)
  Implicit None
  Real, Intent(OUT) :: v1, v3
  Integer, Intent(OUT) :: v2
  Character(Len = *), Intent(IN) :: s1, s2, s3
  Write (*,*) 'Enter the value for ', s1
  Read (*,*) v1
  Write (*,*) 'Enter the value for ', s2
  Read (*,*) v2
  Write (*,*) 'Enter the value for ', s3
  Read (*,*) v3
End Subroutine get_vals


Real Function arith_next(prev_term, index, increment)
! arithmetic series   n + (n + k) + (n + 2*k) + ....
    Implicit None
    Real, Intent(IN) :: prev_term, increment
    Integer, Intent(IN) :: index
    arith_next = prev_term + increment
End Function arith_next

Real Function geom_next(prev_term, index, factor)
! geometric series   n + (n * k) + (n * k^2) + ....
    Implicit None
    Real, Intent(IN) :: prev_term, factor
    Integer, Intent(IN) :: index
    geom_next = prev_term * factor
End Function geom_next
 
Real Function power_next(prev_term, index, power)
! power series  1 + 1/2 + 1/3 + ...
  !               1^2 + 2^2 + 3^2 + ...
    Implicit None
    Real, Intent(IN) :: prev_term, power
    Integer, Intent(IN) :: index
    power_next = index**power
End Function power_next
