# include # include # include "cosine_integral.h" /******************************************************************************/ double ci ( double x ) /******************************************************************************/ /* Purpose: 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: double x: the argument. Output: double ci: the value of Ci(x). */ { double *bj; double el; double eps; int k; int m; double value; double x2; double xa; double xa0; double xa1; double xabs; double xcs; double xf; double xg; double xg1; double xg2; double xr; double xs; double xss; el = 0.5772156649015329; eps = 1.0E-15; x2 = x * x; xabs = fabs ( x ); if ( xabs == 0.0 ) { value = -1.0e+300; } else if ( xabs <= 16.0 ) { xr = -0.25 * x2; value = el + log ( xabs ) + xr; for ( k = 2; k <= 40; k++ ) { xr = - 0.5 * xr * ( k - 1 ) / ( k * k * ( 2 * k - 1 ) ) * x2; value = value + xr; if ( fabs ( xr ) < fabs ( value ) * eps ) { return value; } } } else if ( xabs <= 32.0 ) { m = ( int ) ( 47.2 + 0.82 * xabs ); bj = ( double * ) malloc ( m * sizeof ( double ) ); xa1 = 0.0; xa0 = 1.0E-100; for ( k = m; 1 <= k; k-- ) { xa = 4.0 * k * xa0 / xabs - xa1; bj[k-1] = xa; xa1 = xa0; xa0 = xa; } xs = bj[0]; for ( k = 3; k <= m; k = k + 2 ) { xs = xs + 2.0 * bj[k-1]; } bj[0] = bj[0] / xs; for ( k = 2; k <= m; k++ ) { bj[k-1] = bj[k-1] / xs; } xr = 1.0; xg1 = bj[0]; for ( k = 2; k <= m; k++ ) { xr = 0.25 * xr * pow ( 2.0 * k - 3.0, 2 ) / ( ( k - 1.0 ) * pow ( 2.0 * k - 1.0, 2 ) ) * xabs; xg1 = xg1 + bj[k-1] * xr; } xr = 1.0; xg2 = bj[0]; for ( k = 2; k <= m; k++ ) { xr = 0.25 * xr * pow ( 2.0 * k - 5.0, 2 ) / ( ( k - 1.0 ) * pow ( 2.0 * k - 3.0, 2 ) ) * xabs; xg2 = xg2 + bj[k-1] * xr; } xcs = cos ( xabs / 2.0 ); xss = sin ( xabs / 2.0 ); value = el + log ( xabs ) - xabs * xss * xg1 + 2.0 * xcs * xg2 - 2.0 * xcs * xcs; free ( bj ); } else { xr = 1.0; xf = 1.0; for ( k = 1; k <= 9; k++ ) { xr = -2.0 * xr * k * ( 2 * k - 1 ) / x2; xf = xf + xr; } xr = 1.0 / xabs; xg = xr; for ( k = 1; k <= 8; k++ ) { xr = -2.0 * xr * ( 2 * k + 1 ) * k / x2; xg = xg + xr; } value = xf * sin ( xabs ) / xabs - xg * cos ( xabs ) / xabs; } return value; }