//------------------------------------------------------------------------------
/// 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;
}
Beispiel #2
0
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);
}
Beispiel #4
0
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));
}