private static Complex LogGamma_Stirling(Complex z) { // work in the upper complex plane; i think this isn't actually necessary if (z.Im < 0.0) { return(LogGamma_Stirling(z.Conjugate).Conjugate); } Complex f = (z - 0.5) * ComplexMath.Log(z) - z + Math.Log(Global.TwoPI) / 2.0; // reduce f.Im modulo 2*PI // result is cyclic in f.Im modulo 2*PI, but if f.Im starts off too big, the corrections // applied below will be lost because they are being added to a big number f = new Complex(f.Re, AdvancedMath.Reduce(f.Im, 0.0)); Complex zz = z * z; Complex zp = z; for (int i = 1; i < AdvancedIntegerMath.Bernoulli.Length; i++) { Complex f_old = f; f += AdvancedIntegerMath.Bernoulli[i] / (2 * i) / (2 * i - 1) / zp; if (f == f_old) { return(f); } zp *= zz; } throw new NonconvergenceException(); }