double Specific_heat(double t, double h, double sf2) { /* gsl_function F; double result, abserr; F.function = &Energy; F.params = 0; gsl_deriv_backward(&F, t, 1.0e-5, &result, &abserr); // printf("%f %f %f \n", result, result - 99.0/4.0 * gsl_sf_zeta(11.0/2.0)/gsl_sf_zeta(9.0/2.0) * pow(t, 9.0/2.0) , t); return result; */ if(t <= 1) { return 15.0/4.0 * gsl_sf_zeta(5.0/2.0)/gsl_sf_zeta(3.0/2.0) * pow(t,3.0/2.0); } if(t > 1) { // printf("%f\n", t+15.0*h); return sf2/2.0 + ((Energy(t+2.0*h,0) - Energy(t,0))/(2.0*h) + (Energy(t+3.0*h,0) - Energy(t,0))/(3.0*h) + (Energy(t+4.0*h,0) - Energy(t,0))/(4.0*h) + (Energy(t+6.0*h,0) - Energy(t,0))/(6.0*h) + (Energy(t+7.0*h,0) - Energy(t,0))/(7.0*h) + (Energy(t+9.0*h,0) - Energy(t,0))/(9.0*h) + (Energy(t+10.0*h,0) - Energy(t,0))/(10.0*h) + (Energy(t+12.0*h,0) - Energy(t,0))/(12.0*h) + (Energy(t+13.0*h,0) - Energy(t,0))/(13.0*h) + (Energy(t+15.0*h,0) - Energy(t,0))/(15.0*h))/20.0; } }
double BEF(double p, double t) { double g; int n, N=10; double r[N], sum_accel, err, sum = 0.0; double np1; if(t < 1.0) { g = gsl_sf_zeta(p); printf("error!\n"); } else if(t > 1.0) { // exp(mu(t)/t)^n/n^(p)need mu function gsl_sum_levin_u_workspace * w = gsl_sum_levin_u_alloc(N); for (n = 0; n < N; n++) { np1 = n + 1.0; r[n] = pow(exp( mu(t)/t ) ,np1) / pow(np1, p); sum += r[n]; } gsl_sum_levin_u_accel(r, N, w, &sum_accel, &err); g = sum_accel; gsl_sum_levin_u_free(w); } return g; }
double Energy(double t, void * params) { if(t < 1.0) { return 3.0/2.0 * pow(t,5.0/2.0) * gsl_sf_zeta(5.0/2.0)/gsl_sf_zeta(3.0/2.0); } else if(t > 1.0) { return 3.0/2.0 * pow(t,5.0/2.0) * BEF(5.0/2.0, t)/gsl_sf_zeta(3.0/2.0); } else { return 3.0/2.0 * gsl_sf_zeta(5.0/2.0)/gsl_sf_zeta(3.0/2.0); } }
//高温領域でのmuの温度依存性を調べる関数 double mu(double t) { int j, N; double mu1, mu2, g2=-5.0, g, g_exact; int N2 = 10; double r[N2], sum_accel, err, sum = 0.0; int n; double np1; g_exact = gsl_sf_zeta(3.0/2.0)/pow(t, 3.0/2.0); //partition N = 1000; for(j=0; j<=6.5*N; j++) { mu1 = 0.0 - 1.0*j/N; gsl_sum_levin_u_workspace * w = gsl_sum_levin_u_alloc(N2); for (n = 0; n < N2; n++) { np1 = n + 1.0; r[n] = pow(exp( mu1/t ) ,np1) / pow(np1, 3.0/2.0); sum += r[n]; } gsl_sum_levin_u_accel(r, N2, w, &sum_accel, &err); g = sum_accel; gsl_sum_levin_u_free(w); if( fabs( g - g_exact ) < fabs( g2 - g_exact ) ) { //printf("%f %f %20.16f %20.16f %20.16f\n",t, mu1, g, g2, g_exact); }else { //printf("%f %f %20.16f %20.16f %20.16f\n",t, mu1, g, g2, g_exact); break; } g2 = g; mu2 = mu1; } return mu2; }
/* Sample from zeta distribution * * This is an inverse CDF method. It works by using an * approximation of the Hurwitz Zeta function and then * walking left or right until we get to the correct point. * The approximation is good for large values so usually we * only have to walk left or right a few steps for small * values. */ long Zeta(RndState *S, double s) { double v=(1-Uniform(S))*gsl_sf_zeta(s); double k0, k=round(pow(v*(s-1),1/(1-s))); // approx inverse of hzeta double zk0, zk=gsl_sf_hzeta(s,k); if (zk>=v) { do { k0=k; zk0=zk; k=k0+1; zk=zk0-pow(k0,-s); } while (zk>=v && zk!=zk0); return (long)k0; } else { do { k0=k; zk0=zk; k=k0-1; zk=zk0+pow(k,-s); } while (zk<v && zk!=zk0); return (long)k; } }
int main() { typedef double T; #define SC_(x) static_cast<double>(x) #include "zeta_data.ipp" #include "zeta_neg_data.ipp" #include "zeta_1_up_data.ipp" #include "zeta_1_below_data.ipp" add_data(zeta_data); add_data(zeta_neg_data); add_data(zeta_1_up_data); add_data(zeta_1_below_data); unsigned data_total = data.size(); screen_data([](const std::vector<double>& v){ return boost::math::zeta(v[0]); }, [](const std::vector<double>& v){ return v[1]; }); #if defined(TEST_LIBSTDCXX) && !defined(COMPILER_COMPARISON_TABLES) screen_data([](const std::vector<double>& v){ return std::tr1::riemann_zeta(v[0]); }, [](const std::vector<double>& v){ return v[1]; }); #endif #if defined(TEST_GSL) && !defined(COMPILER_COMPARISON_TABLES) screen_data([](const std::vector<double>& v){ return gsl_sf_zeta(v[0]); }, [](const std::vector<double>& v){ return v[1]; }); #endif unsigned data_used = data.size(); std::string function = "zeta[br](" + boost::lexical_cast<std::string>(data_used) + "/" + boost::lexical_cast<std::string>(data_total) + " tests selected)"; std::string function_short = "zeta"; double time = exec_timed_test([](const std::vector<double>& v){ return boost::math::zeta(v[0]); }); std::cout << time << std::endl; #if !defined(COMPILER_COMPARISON_TABLES) && (defined(TEST_GSL) || defined(TEST_RMATH) || defined(TEST_LIBSTDCXX)) report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, boost_name()); #endif report_execution_time(time, std::string("Compiler Comparison on ") + std::string(platform_name()), function_short, compiler_name() + std::string("[br]") + boost_name()); // // Boost again, but with promotion to long double turned off: // #if !defined(COMPILER_COMPARISON_TABLES) if(sizeof(long double) != sizeof(double)) { double time = exec_timed_test([](const std::vector<double>& v){ return boost::math::zeta(v[0], boost::math::policies::make_policy(boost::math::policies::promote_double<false>())); }); std::cout << time << std::endl; #if !defined(COMPILER_COMPARISON_TABLES) && (defined(TEST_GSL) || defined(TEST_RMATH) || defined(TEST_LIBSTDCXX)) report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, boost_name() + "[br]promote_double<false>"); #endif report_execution_time(time, std::string("Compiler Comparison on ") + std::string(platform_name()), function_short, compiler_name() + std::string("[br]") + boost_name() + "[br]promote_double<false>"); } #endif #if defined(TEST_LIBSTDCXX) && !defined(COMPILER_COMPARISON_TABLES) time = exec_timed_test([](const std::vector<double>& v){ return std::tr1::riemann_zeta(v[0]); }); std::cout << time << std::endl; report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "tr1/cmath"); #endif #if defined(TEST_GSL) && !defined(COMPILER_COMPARISON_TABLES) time = exec_timed_test([](const std::vector<double>& v){ return gsl_sf_zeta(v[0]); }); std::cout << time << std::endl; report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "GSL " GSL_VERSION); #endif return 0; }
double pdf_Zeta(double s, long x) { return pow(x,-s)/gsl_sf_zeta(s); }