double tgamma(double x) /* Gamma function */ { int sign; if (x == 0.0) { /* Pole Error */ errno = ERANGE; return 1/x < 0 ? -HUGE_VAL : HUGE_VAL; } if (isinf(x)) { if (x < 0) goto domain_error; return x; } if (x < 0) { static double zero = 0.0; double i, f; f = modf(-x, &i); if (f == 0.0) { /* Domain Error */ domain_error: errno = EDOM; return zero/zero; } #ifndef HAVE_LGAMMA_R sign = (fmod(i, 2.0) != 0.0) ? 1 : -1; return sign * PI / (sin(PI * f) * exp(loggamma(1 - x))); #endif } #ifndef HAVE_LGAMMA_R return exp(loggamma(x)); #else x = lgamma_r(x, &sign); return sign * exp(x); #endif }
/* Γ関数の値を求める */ double gamma(double x) { if (x < 0) return M_PI / (sin(M_PI * x) * exp(loggamma(1 - x))); else return exp(loggamma(x)); }
/* the natural logarithm of the absolute value of the Gamma function */ double lgamma_r(double x, int *signp) { if (x <= 0) { double i, f, s; f = modf(-x, &i); if (f == 0.0) { /* pole error */ *signp = signbit(x) ? -1 : 1; errno = ERANGE; return HUGE_VAL; } *signp = (fmod(i, 2.0) != 0.0) ? 1 : -1; s = sin(PI * f); if (s < 0) s = -s; return LOG_PI - log(s) - loggamma(1 - x); } *signp = 1; return loggamma(x); }
double CMultinomialTable::CalcLogZ( double *alpha , double *addData ) { double sum = 0; double z = 0; for(int i=0 ; i<m_dim ; i++ ) { if( addData ) { sum += (alpha[i] + addData[i]); z += loggamma( alpha[i] + addData[i] ); } else { sum += alpha[i]; z += loggamma( alpha[i] ); } } z -= loggamma( sum ); return z; }