function ci ( x ) !*****************************************************************************80 ! !! ci() computes the cosine integral Ci(x). ! ! Licensing: ! ! This routine is copyrighted by Shanjie Zhang and Jianming Jin. However, ! they give permission to incorporate this routine into a user program ! provided that the copyright is acknowledged. ! ! Modified: ! ! 11 August 2025 ! ! Author: ! ! Original Fortran77 version by Shanjie Zhang, Jianming Jin. ! This version by John Burkardt. ! ! Reference: ! ! Shanjie Zhang, Jianming Jin, ! Computation of Special Functions, ! Wiley, 1996, ! ISBN: 0-471-11963-6, ! LC: QA351.C45. ! ! Input: ! ! real ( kind = rk8 ) x: the argument. ! ! Output: ! ! real ( kind = rk8 ) ci: the value of Ci(x). ! implicit none integer, parameter :: rk8 = kind ( 1.0D+00 ) real ( kind = rk8 ) bj(101) real ( kind = rk8 ) ci real ( kind = rk8 ) el real ( kind = rk8 ) eps integer k integer m real ( kind = rk8 ) p2 real ( kind = rk8 ) x real ( kind = rk8 ) x2 real ( kind = rk8 ) xa real ( kind = rk8 ) xa0 real ( kind = rk8 ) xa1 real ( kind = rk8 ) xabs real ( kind = rk8 ) xcs real ( kind = rk8 ) xf real ( kind = rk8 ) xg real ( kind = rk8 ) xg1 real ( kind = rk8 ) xg2 real ( kind = rk8 ) xr real ( kind = rk8 ) xs real ( kind = rk8 ) xss p2 = 1.570796326794897D+00 el = 0.5772156649015329D+00 eps = 1.0D-15 x2 = x * x xabs = abs ( x ) if ( xabs == 0.0D+00 ) then ci = -1.0D+300 else if ( xabs <= 16.0D+00 ) then xr = -0.25D+00 * x2 ci = el + log ( xabs ) + xr do k = 2, 40 xr = -0.5D+00 * xr * ( k - 1 ) / ( k * k * ( 2 * k - 1 ) ) * x2 ci = ci + xr if ( abs ( xr ) < abs ( ci ) * eps ) then return end if end do else if ( xabs <= 32.0D+00 ) then m = int ( 47.2D+00 + 0.82D+00 * xabs ) xa1 = 0.0D+00 xa0 = 1.0D-100 do k = m, 1, -1 xa = 4.0D+00 * k * xa0 / xabs - xa1 bj(k) = xa xa1 = xa0 xa0 = xa end do xs = bj(1) do k = 3, m, 2 xs = xs + 2.0D+00 * bj(k) end do bj(1) = bj(1) / xs do k = 2, m bj(k) = bj(k) / xs end do xr = 1.0D+00 xg1 = bj(1) do k = 2, m xr = 0.25D+00 * xr * ( 2.0D+00 * k - 3.0D+00 )**2 & / ( ( k - 1.0D+00 ) * ( 2.0D+00 * k - 1.0D+00 )**2 ) * xabs xg1 = xg1 + bj(k) * xr end do xr = 1.0D+00 xg2 = bj(1) do k = 2, m xr = 0.25D+00 * xr * ( 2.0D+00 * k - 5.0D+00 )**2 & / ( ( k - 1.0D+00 ) * ( 2.0D+00 * k - 3.0D+00 )**2 ) * xabs xg2 = xg2 + bj(k) * xr end do xcs = cos ( xabs / 2.0D+00 ) xss = sin ( xabs / 2.0D+00 ) ci = el + log ( xabs ) - xabs * xss * xg1 + 2.0 * xcs * xg2 & - 2.0 * xcs * xcs else xr = 1.0D+00 xf = 1.0D+00 do k = 1, 9 xr = -2.0D+00 * xr * k * ( 2 * k - 1 ) / x2 xf = xf + xr end do xr = 1.0D+00 / xabs xg = xr do k = 1, 8 xr = -2.0D+00 * xr * ( 2 * k + 1 ) * k / x2 xg = xg + xr end do ci = xf * sin ( xabs ) / xabs - xg * cos ( xabs ) / xabs end if return end