//------------------------------------------------------------------------------ /// Trilogarithm \f$ {\rm Li}_3(x) \f$ // This uses the relation Li3[z] = Log[z]^2/2 (Log[1 - z] - D2[-Log[z]]/2) + Log[z] PolyLog[2, z] + Zeta[3] // where D2 is the 2nd order Debye function inline double trilog(const double x) { if (x <= 0.1) return x*(1. + x*(1./8. + x*(1./27. + x*(1./64. + x*(1./125. + x*(1./216. + x*(1./343. + x*(1./512. + x*(1./729. + x*(1./1000. + x*(1./1331. + x/1728.))))))))))); if (x == 1.) return 1.2020569031595942853997381615114500; const double lnx = log(x); return lnx*(gsl_sf_dilog(x) + 0.5*lnx*(log1p(-x) - 0.5*gsl_sf_debye_2(-lnx))) + 1.2020569031595942853997381615114500; }
double Polylogarithms::Li3(const double x) const { double Li3 = 0.0; if (x < 0.0) Li3 = -gsl_sf_fermi_dirac_2(log(-x)); else if (x == 0.0) Li3 = 0.0; else if (x > 0.0 && x < 0.5) { double log_1mx = log(1.0 - x); double lfactorial = 1.0, kfactorial = 1.0; for (int l=0; l<19; l++) { if (l!=0) lfactorial *= (double)l; kfactorial = 1.0; for (int k=0; k<19; k++) { if (k!=0) kfactorial *= (double)k; Li3 += B[l]*B[k]/((double)l+1.0)/((double)l+(double)k+1.0) /lfactorial/kfactorial * pow(-log_1mx, (double)l+(double)k+1.0); } } } else if (x == 0.5) { double log2 = log(2.0); double zeta3 = gsl_sf_zeta_int(3); Li3 = (4.0*pow(log2, 3.0) - 2.0*M_PI*M_PI*log2 + 21.0*zeta3)/24.0; } else if (x > 0.5 && x < 1.0) { double log_x = log(x); double S12 = 0.0, lfactorial = 1.0; for (int l=0; l<19; l++) { if (l!=0) lfactorial *= (double)l; S12 += 0.5 * B[l]/((double)l+2.0)/lfactorial * pow(-log_x, (double)l+2.0); } Li3 = - S12 - log_x*gsl_sf_dilog(1.0-x) - 0.5*log_x*log_x*log(1.0-x) + gsl_sf_zeta_int(2)*log_x + gsl_sf_zeta_int(3); } else if (x == 1.0) Li3 = gsl_sf_zeta_int(3); else throw std::runtime_error("Polylogarithms::Li3(): x is out of range!"); return (Li3); }
//------------------------------------------------------------------------------ /// Dilogarithm \f$ {\rm Li}_2(x) \f$ inline double dilog(const double x) { return gsl_sf_dilog(x); }
double I1(double y0, double y) { double p1 = 0.5*(y0+y)*gsl_sf_log((1.0+exp((y0+y)/2.0))/(1-exp((-y0+y)/2))); double p2 = -0.5*(y0-y)*gsl_sf_log((1.0+exp((y0-y)/2.0))/(1-exp((-y0-y)/2))); return p1+p2+gsl_sf_dilog(-exp(y0/2.0+y/2.0))+gsl_sf_dilog(exp(-y0/2.0-y/2.0))-gsl_sf_dilog(-exp(y0/2.0-y/2.0))-gsl_sf_dilog(exp(-y0/2.0+y/2.0)); }