static PyObject* gsl_sf_gauss(PyObject *self, PyObject *args ) { const double norm=1.0/M_SQRT2/M_SQRTPI; double x; double sigma=1.0; double mu=0; double tmp; gsl_sf_result result; int err_result; PyObject* python_result; if (!PyArg_ParseTuple(args, "d|dd:gauss", &x, &mu, &sigma)) return NULL; /*use tmp as temporary variable*/ tmp=((x-mu)/sigma); err_result=gsl_sf_exp_mult_e(tmp*tmp/-2.0, norm/sigma, &result); if (err_result) return NULL; python_result=PyTuple_New(2); if (python_result==NULL) return NULL; PyTuple_SetItem(python_result,0,PyFloat_FromDouble(result.val)); PyTuple_SetItem(python_result,1,PyFloat_FromDouble(result.err)); return python_result; }
double gsl_sf_exp_mult(const double x, const double y) { EVAL_RESULT(gsl_sf_exp_mult_e(x, y, &result)); }
int gsl_sf_exprel_n_e(const int N, const double x, gsl_sf_result * result) { if(N < 0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(fabs(x) < GSL_ROOT3_DBL_EPSILON * N) { result->val = 1.0 + x/(N+1) * (1.0 + x/(N+2)); result->err = 2.0 * GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(N == 0) { return gsl_sf_exp_e(x, result); } else if(N == 1) { return gsl_sf_exprel_e(x, result); } else if(N == 2) { return gsl_sf_exprel_2_e(x, result); } else { if(x > N && (-x + N*(1.0 + log(x/N)) < GSL_LOG_DBL_EPSILON)) { /* x is much larger than n. * Ignore polynomial part, so * exprel_N(x) ~= e^x N!/x^N */ gsl_sf_result lnf_N; double lnr_val; double lnr_err; double lnterm; gsl_sf_lnfact_e(N, &lnf_N); lnterm = N*log(x); lnr_val = x + lnf_N.val - lnterm; lnr_err = GSL_DBL_EPSILON * (fabs(x) + fabs(lnf_N.val) + fabs(lnterm)); lnr_err += lnf_N.err; return gsl_sf_exp_err_e(lnr_val, lnr_err, result); } else if(x > N) { /* Write the identity * exprel_n(x) = e^x n! / x^n (1 - Gamma[n,x]/Gamma[n]) * then use the asymptotic expansion * Gamma[n,x] ~ x^(n-1) e^(-x) (1 + (n-1)/x + (n-1)(n-2)/x^2 + ...) */ double ln_x = log(x); gsl_sf_result lnf_N; double lg_N; double lnpre_val; double lnpre_err; gsl_sf_lnfact_e(N, &lnf_N); /* log(N!) */ lg_N = lnf_N.val - log(N); /* log(Gamma(N)) */ lnpre_val = x + lnf_N.val - N*ln_x; lnpre_err = GSL_DBL_EPSILON * (fabs(x) + fabs(lnf_N.val) + fabs(N*ln_x)); lnpre_err += lnf_N.err; if(lnpre_val < GSL_LOG_DBL_MAX - 5.0) { int stat_eG; gsl_sf_result bigG_ratio; gsl_sf_result pre; int stat_ex = gsl_sf_exp_err_e(lnpre_val, lnpre_err, &pre); double ln_bigG_ratio_pre = -x + (N-1)*ln_x - lg_N; double bigGsum = 1.0; double term = 1.0; int k; for(k=1; k<N; k++) { term *= (N-k)/x; bigGsum += term; } stat_eG = gsl_sf_exp_mult_e(ln_bigG_ratio_pre, bigGsum, &bigG_ratio); if(stat_eG == GSL_SUCCESS) { result->val = pre.val * (1.0 - bigG_ratio.val); result->err = pre.val * (2.0*GSL_DBL_EPSILON + bigG_ratio.err); result->err += pre.err * fabs(1.0 - bigG_ratio.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_ex; } else { result->val = 0.0; result->err = 0.0; return stat_eG; } } else { OVERFLOW_ERROR(result); } } else if(x > -10.0*N) { return exprel_n_CF(N, x, result); } else { /* x -> -Inf asymptotic: * exprel_n(x) ~ e^x n!/x^n - n/x (1 + (n-1)/x + (n-1)(n-2)/x + ...) * ~ - n/x (1 + (n-1)/x + (n-1)(n-2)/x + ...) */ double sum = 1.0; double term = 1.0; int k; for(k=1; k<N; k++) { term *= (N-k)/x; sum += term; } result->val = -N/x * sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } }
/** * C++ version of gsl_sf_exp_mult_e(). * Exponentiate and multiply by a given factor: y * Exp(x) * @param x A real number * @param y A real number * @param result The result as a @c gsl::sf::result object * @return GSL_SUCCESS or GSL_EUNDRFLW or GSL_EOVRFLW */ inline int exp_mult_e( double const x, double const y, result& result ){ return gsl_sf_exp_mult_e( x, y, &result ); }