func Lngamma_sgn_sing(N int, eps float64, lng *Result, sgn *float64) error { if eps == 0.0 { lng.val = 0.0 lng.err = 0.0 *sgn = 0.0 return err.EDOM } else if N == 1 { /* calculate series for * g = eps gamma(-1+eps) + 1 + eps/2 (1+3eps)/(1-eps^2) * double-precision for |eps| < 0.02 */ c0 := 0.07721566490153286061 c1 := 0.08815966957356030521 c2 := -0.00436125434555340577 c3 := 0.01391065882004640689 c4 := -0.00409427227680839100 c5 := 0.00275661310191541584 c6 := -0.00124162645565305019 c7 := 0.00065267976121802783 c8 := -0.00032205261682710437 c9 := 0.00016229131039545456 g5 := c5 + eps*(c6+eps*(c7+eps*(c8+eps*c9))) g := eps * (c0 + eps*(c1+eps*(c2+eps*(c3+eps*(c4+eps*g5))))) /* calculate eps gamma(-1+eps), a negative quantity */ gam_e := g - 1.0 - 0.5*eps*(1.0+3.0*eps)/(1.0-eps*eps) lng.val = math.Log(math.Abs(gam_e) / math.Abs(eps)) lng.err = 2.0 * gsl.DBL_EPSILON * math.Abs(lng.val) if eps > 0.0 { *sgn = -1.0 } else { *sgn = 1.0 } return err.SUCCESS } var g float64 /* series for sin(Pi(N+1-eps))/(Pi eps) modulo the sign * double-precision for |eps| < 0.02 */ cs1 := -1.6449340668482264365 cs2 := 0.8117424252833536436 cs3 := -0.1907518241220842137 cs4 := 0.0261478478176548005 cs5 := -0.0023460810354558236 e2 := eps * eps sin_ser := 1.0 + e2*(cs1+e2*(cs2+e2*(cs3+e2*(cs4+e2*cs5)))) /* calculate series for ln(gamma(1+N-eps)) * double-precision for |eps| < 0.02 */ aeps := math.Abs(eps) var c1, c2, c3, c4, c5, c6, c7, lng_ser float64 var c0, psi_0, psi_1, psi_2, psi_3, psi_4, psi_5, psi_6 *Result psi_2.val = 0.0 psi_3.val = 0.0 psi_4.val = 0.0 psi_5.val = 0.0 psi_6.val = 0.0 Lnfact_e(N, c0) Psi_int_e(N+1, psi_0) Psi_1_int_e(N+1, psi_1) switch { case aeps > 0.00001: Psi_n_e(2, float64(N)+1.0, psi_2) case aeps > 0.0002: Psi_n_e(3, float64(N)+1.0, psi_3) case aeps > 0.001: Psi_n_e(4, float64(N)+1.0, psi_4) case aeps > 0.005: Psi_n_e(5, float64(N)+1.0, psi_5) case aeps > 0.01: Psi_n_e(6, float64(N)+1.0, psi_6) } c1 = psi_0.val c2 = psi_1.val / 2.0 c3 = psi_2.val / 6.0 c4 = psi_3.val / 24.0 c5 = psi_4.val / 120.0 c6 = psi_5.val / 720.0 c7 = psi_6.val / 5040.0 lng_ser = c0.val - eps*(c1-eps*(c2-eps*(c3-eps*(c4-eps*(c5-eps*(c6-eps*c7)))))) /* calculate * g = ln(|eps gamma(-N+eps)|) * = -ln(gamma(1+N-eps)) + ln(|eps Pi/sin(Pi(N+1+eps))|) */ g = -lng_ser - math.Log(sin_ser) lng.val = g - math.Log(math.Abs(eps)) lng.err = c0.err + 2.0*gsl.DBL_EPSILON*(math.Abs(g)+math.Abs(lng.val)) if eps > 0.0 { *sgn = 1.0 } else { *sgn = -1.0 } if gsl.IsOdd(N) { *sgn *= -1.0 } else { *sgn *= 1.0 } return err.SUCCESS }
func Exprel_n_CF(N int, x float64, result *Result) error { RECUR_BIG := gsl.SQRT_DBL_MAX maxiter := 5000 n := 1 Anm2 := 1.0 Bnm2 := 0.0 Anm1 := 0.0 Bnm1 := 1.0 a1 := 1.0 b1 := 1.0 a2 := -x b2 := float64(N) + 1.0 var an, bn, old_fn, del float64 An := b1*Anm1 + a1*Anm2 /* A1 */ Bn := b1*Bnm1 + a1*Bnm2 /* B1 */ /* One explicit step, before we get to the main pattern. */ n++ Anm2 = Anm1 Bnm2 = Bnm1 Anm1 = An Bnm1 = Bn An = b2*Anm1 + a2*Anm2 /* A2 */ Bn = b2*Bnm1 + a2*Bnm2 /* B2 */ fn := An / Bn for n < maxiter { n++ Anm2 = Anm1 Bnm2 = Bnm1 Anm1 = An Bnm1 = Bn if gsl.IsOdd(n) { an = (float64(n-1) / 2.0) * x } else { an = -(float64(N) + (float64(n) / 2) - 1.0) * x } bn = float64(N + n - 1) An = bn*Anm1 + an*Anm2 Bn = bn*Bnm1 + an*Bnm2 if math.Abs(An) > RECUR_BIG || math.Abs(Bn) > RECUR_BIG { An /= RECUR_BIG Bn /= RECUR_BIG Anm1 /= RECUR_BIG Bnm1 /= RECUR_BIG Anm2 /= RECUR_BIG Bnm2 /= RECUR_BIG } old_fn = fn fn = An / Bn del = old_fn / fn if math.Abs(del-1.0) < 2.0*gsl.DBL_EPSILON { break } } result.val = fn result.err = 2.0 * (float64(n) + 1.0) * gsl.DBL_EPSILON * math.Abs(fn) if n == maxiter { return err.EMAXITER } return err.SUCCESS }