Alex Bikfalvi
SimStream Documentation
Zeta.cpp
00001 #include "Headers.h" 00002 #include "Zeta.h" 00003 00004 00005 /* coefficients for Maclaurin summation in hzeta() 00006 * B_{2j}/(2j)! 00007 */ 00008 static double hzeta_c[15] = { 00009 1.00000000000000000000000000000, 00010 0.083333333333333333333333333333, 00011 -0.00138888888888888888888888888889, 00012 0.000033068783068783068783068783069, 00013 -8.2671957671957671957671957672e-07, 00014 2.0876756987868098979210090321e-08, 00015 -5.2841901386874931848476822022e-10, 00016 1.3382536530684678832826980975e-11, 00017 -3.3896802963225828668301953912e-13, 00018 8.5860620562778445641359054504e-15, 00019 -2.1748686985580618730415164239e-16, 00020 5.5090028283602295152026526089e-18, 00021 -1.3954464685812523340707686264e-19, 00022 3.5347070396294674716932299778e-21, 00023 -8.9535174270375468504026113181e-23 00024 }; 00025 00026 00027 int HZeta(const double s, const double q, MathResult * result) 00028 { 00029 /* CHECK_POINTER(result) */ 00030 00031 if(s <= 1.0 || q <= 0.0) 00032 { 00033 DOMAIN_ERROR(result); 00034 } 00035 else 00036 { 00037 const double max_bits = 54.0; 00038 const double ln_term0 = -s * log(q); 00039 00040 if(ln_term0 < MATH_LOG_DBL_MIN + 1.0) 00041 { 00042 UNDERFLOW_ERROR(result); 00043 } 00044 else if(ln_term0 > MATH_LOG_DBL_MAX - 1.0) 00045 { 00046 OVERFLOW_ERROR (result); 00047 } 00048 else if((s > max_bits && q < 1.0) || (s > 0.5*max_bits && q < 0.25)) 00049 { 00050 result->val = pow(q, -s); 00051 result->err = 2.0 * MATH_DBL_EPSILON * fabs(result->val); 00052 return MATH_SUCCESS; 00053 } 00054 else if(s > 0.5*max_bits && q < 1.0) 00055 { 00056 const double p1 = pow(q, -s); 00057 const double p2 = pow(q/(1.0+q), s); 00058 const double p3 = pow(q/(2.0+q), s); 00059 result->val = p1 * (1.0 + p2 + p3); 00060 result->err = MATH_DBL_EPSILON * (0.5*s + 2.0) * fabs(result->val); 00061 return MATH_SUCCESS; 00062 } 00063 else 00064 { 00065 /* Euler-Maclaurin summation formula 00066 * [Moshier, p. 400, with several typo corrections] 00067 */ 00068 const int jmax = 12; 00069 const int kmax = 10; 00070 int j, k; 00071 const double pmax = pow(kmax + q, -s); 00072 double scp = s; 00073 double pcp = pmax / (kmax + q); 00074 double ans = pmax*((kmax+q)/(s-1.0) + 0.5); 00075 00076 for(k=0; k<kmax; k++) 00077 { 00078 ans += pow(k + q, -s); 00079 } 00080 00081 for(j=0; j<=jmax; j++) 00082 { 00083 double delta = hzeta_c[j+1] * scp * pcp; 00084 ans += delta; 00085 if(fabs(delta/ans) < 0.5*MATH_DBL_EPSILON) break; 00086 scp *= (s+2*j+1)*(s+2*j+2); 00087 pcp /= (kmax + q)*(kmax + q); 00088 } 00089 00090 result->val = ans; 00091 result->err = 2.0 * (jmax + 1.0) * MATH_DBL_EPSILON * fabs(ans); 00092 return MATH_SUCCESS; 00093 } 00094 } 00095 } 00096
Last updated: February 8, 2011