Пример #1
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);
}
Пример #2
0
 /**
  * C++ version of gsl_sf_fermi_dirac_2().
  * F_2(x): F_j(x)   := 1/Gamma[j+1] Integral[ t^j /(Exp[t-x] + 1), {t,0,Infinity}]
  * @param x A real number
  * @return The function value
  */
 inline double fermi_dirac_2( double const x ){
   return gsl_sf_fermi_dirac_2( x ); }