/// Clausen function of order 2. double clausen_c_2(double w) { gsl_sf_result result; int stat = gsl_sf_clausen_e(w, &result); if (stat != GSL_SUCCESS) { std::ostringstream msg("Error in clausen_c_2:"); msg << " w=" << w; throw std::runtime_error(msg.str()); } else return result.val; }
/* Evaluate a series for Li_2(z) when |z| is near 1. * This is uniformly good away from z=1. * * Li_2(z) = Sum[ a^n/n! H_n(theta), {n, 0, Infinity}] * * where * H_n(theta) = Sum[ e^(i m theta) m^n / m^2, {m, 1, Infinity}] * a = ln(r) * * H_0(t) = Gl_2(t) + i Cl_2(t) * H_1(t) = 1/2 ln(2(1-c)) + I atan2(-s, 1-c) * H_2(t) = -1/2 + I/2 s/(1-c) * H_3(t) = -1/2 /(1-c) * H_4(t) = -I/2 s/(1-c)^2 * H_5(t) = 1/2 (2 + c)/(1-c)^2 * H_6(t) = I/2 s/(1-c)^5 (8(1-c) - s^2 (3 + c)) */ static int dilogc_series_3( const double r, const double x, const double y, gsl_sf_result * real_result, gsl_sf_result * imag_result ) { const double theta = atan2(y, x); const double cos_theta = x/r; const double sin_theta = y/r; const double a = log(r); const double omc = 1.0 - cos_theta; const double omc2 = omc*omc; double H_re[7]; double H_im[7]; double an, nfact; double sum_re, sum_im; gsl_sf_result Him0; int n; H_re[0] = M_PI*M_PI/6.0 + 0.25*(theta*theta - 2.0*M_PI*fabs(theta)); gsl_sf_clausen_e(theta, &Him0); H_im[0] = Him0.val; H_re[1] = -0.5*log(2.0*omc); H_im[1] = -atan2(-sin_theta, omc); H_re[2] = -0.5; H_im[2] = 0.5 * sin_theta/omc; H_re[3] = -0.5/omc; H_im[3] = 0.0; H_re[4] = 0.0; H_im[4] = -0.5*sin_theta/omc2; H_re[5] = 0.5 * (2.0 + cos_theta)/omc2; H_im[5] = 0.0; H_re[6] = 0.0; H_im[6] = 0.5 * sin_theta/(omc2*omc2*omc) * (8.0*omc - sin_theta*sin_theta*(3.0 + cos_theta)); sum_re = H_re[0]; sum_im = H_im[0]; an = 1.0; nfact = 1.0; for(n=1; n<=6; n++) { double t; an *= a; nfact *= n; t = an/nfact; sum_re += t * H_re[n]; sum_im += t * H_im[n]; } real_result->val = sum_re; real_result->err = 2.0 * 6.0 * GSL_DBL_EPSILON * fabs(sum_re) + fabs(an/nfact); imag_result->val = sum_im; imag_result->err = 2.0 * 6.0 * GSL_DBL_EPSILON * fabs(sum_im) + Him0.err + fabs(an/nfact); return GSL_SUCCESS; }
int gsl_sf_complex_dilog_xy_e( const double x, const double y, gsl_sf_result * real_dl, gsl_sf_result * imag_dl ) { const double zeta2 = M_PI*M_PI/6.0; const double r2 = x*x + y*y; if(y == 0.0) { if(x >= 1.0) { imag_dl->val = -M_PI * log(x); imag_dl->err = 2.0 * GSL_DBL_EPSILON * fabs(imag_dl->val); } else { imag_dl->val = 0.0; imag_dl->err = 0.0; } return gsl_sf_dilog_e(x, real_dl); } else if(fabs(r2 - 1.0) < GSL_DBL_EPSILON) { /* Lewin A.2.4.1 and A.2.4.2 */ const double theta = atan2(y, x); const double term1 = theta*theta/4.0; const double term2 = M_PI*fabs(theta)/2.0; real_dl->val = zeta2 + term1 - term2; real_dl->err = 2.0 * GSL_DBL_EPSILON * (zeta2 + term1 + term2); return gsl_sf_clausen_e(theta, imag_dl); } else if(r2 < 1.0) { return dilogc_unitdisk(x, y, real_dl, imag_dl); } else { /* Reduce argument to unit disk. */ const double r = sqrt(r2); const double x_tmp = x/r2; const double y_tmp = -y/r2; /* const double r_tmp = 1.0/r; */ gsl_sf_result result_re_tmp, result_im_tmp; const int stat_dilog = dilogc_unitdisk(x_tmp, y_tmp, &result_re_tmp, &result_im_tmp); /* Unwind the inversion. * * Li_2(z) + Li_2(1/z) = -zeta(2) - 1/2 ln(-z)^2 */ const double theta = atan2(y, x); const double theta_abs = fabs(theta); const double theta_sgn = ( theta < 0.0 ? -1.0 : 1.0 ); const double ln_minusz_re = log(r); const double ln_minusz_im = theta_sgn * (theta_abs - M_PI); const double lmz2_re = ln_minusz_re*ln_minusz_re - ln_minusz_im*ln_minusz_im; const double lmz2_im = 2.0*ln_minusz_re*ln_minusz_im; real_dl->val = -result_re_tmp.val - 0.5 * lmz2_re - zeta2; real_dl->err = result_re_tmp.err + 2.0*GSL_DBL_EPSILON*(0.5 * fabs(lmz2_re) + zeta2); imag_dl->val = -result_im_tmp.val - 0.5 * lmz2_im; imag_dl->err = result_im_tmp.err + 2.0*GSL_DBL_EPSILON*fabs(lmz2_im); return stat_dilog; } }
double gsl_sf_clausen(const double x) { EVAL_RESULT(gsl_sf_clausen_e(x, &result)); }