private static DoubleDouble LogGamma_ShiftToZetaSeries(DoubleDouble x) { Debug.Assert(x >= 1.5); DoubleDouble s = DoubleDouble.Zero; while (x > 2.5) { x -= DoubleDouble.One; s += DoubleDouble.Log(x); } DoubleDouble y = x - 2.0; Debug.Assert(DoubleDouble.Abs(y) <= 0.5); return(LogGammaTwoPlus(y) + s); }
private static DoubleDouble ZetaMinusOne(int n) { // For n < ~16, we would needs more than 255 terms. // Look into using Euler-Maclauren to accelerate. DoubleDouble s = DoubleDouble.Zero; for (int k = 2; k < Global.SeriesMax; k++) { DoubleDouble s_old = s; s += DoubleDouble.Pow(k, -n); if (s == s_old) { return(s); } } throw new NonconvergenceException(); }
private static DoubleDouble Erf_Series(DoubleDouble x) { DoubleDouble mx2 = -(x * x); DoubleDouble t = DoubleDouble.One; DoubleDouble f = t; for (int k = 1; k < 100; k++) { DoubleDouble f_old = f; t *= mx2 / k; f += t / (2 * k + 1); if (f == f_old) { return((2.0 / DoubleDouble.Sqrt(DoubleDouble.Pi)) * x * f); } } throw new InvalidOperationException(); }
private static DoubleDouble Sin_Series(DoubleDouble x) { DoubleDouble mx2 = -x * x; DoubleDouble t = x; DoubleDouble s = t; for (int k = 3; k < Global.SeriesMax; k += 2) { DoubleDouble s_old = s; t *= mx2 / (k * (k - 1)); s += t; if (s == s_old) { return(s); } } throw new NonconvergenceException(); }
private static DoubleDouble BernoulliSum(DoubleDouble x) { DoubleDouble rxPower = 1.0 / x; DoubleDouble rxSquared = rxPower * rxPower; DoubleDouble f = 0.5 * Bernoulli[1] * rxPower; for (int k = 2; k < Bernoulli.Length; k++) { DoubleDouble f_old = f; rxPower *= rxSquared; f += Bernoulli[k] / ((2 * k) * (2 * k - 1)) * rxPower; if (f == f_old) { return(f); } } throw new NonconvergenceException(); }
private static DoubleDouble[] InitializeZetaMinusOne() { DoubleDouble[] zetaMinusOne = new DoubleDouble[64]; zetaMinusOne[0] = -1.5; zetaMinusOne[1] = Double.PositiveInfinity; zetaMinusOne[2] = new DoubleDouble("0.64493406684822643647241516664602519"); zetaMinusOne[3] = new DoubleDouble("0.20205690315959428539973816151144999"); zetaMinusOne[4] = new DoubleDouble("0.082323233711138191516003696541167903"); zetaMinusOne[5] = new DoubleDouble("0.036927755143369926331365486457034168"); zetaMinusOne[6] = new DoubleDouble("0.017343061984449139714517929790920528"); zetaMinusOne[7] = new DoubleDouble("8.3492773819228268397975498497967596E-3"); zetaMinusOne[8] = new DoubleDouble("4.0773561979443393786852385086524653E-3"); zetaMinusOne[9] = new DoubleDouble("2.0083928260822144178527692324120605E-3"); zetaMinusOne[10] = new DoubleDouble("9.9457512781808533714595890031901701E-4"); zetaMinusOne[11] = new DoubleDouble("4.9418860411946455870228252646993647E-4"); zetaMinusOne[12] = new DoubleDouble("2.4608655330804829863799804773967096E-4"); zetaMinusOne[13] = new DoubleDouble("1.2271334757848914675183652635739571E-4"); zetaMinusOne[14] = new DoubleDouble("6.1248135058704829258545105135333747E-5"); zetaMinusOne[15] = new DoubleDouble("3.0588236307020493551728510645062588E-5"); return(zetaMinusOne); }
public static DoubleDouble Cos(DoubleDouble x) { RangeReduction(x, out long z0, out DoubleDouble z1); DoubleDouble x1 = z1 * PiOverTwo; switch (MoreMath.Mod(z0, 4L)) { case 0L: return(Cos_Series(x1)); case 1L: return(-Sin_Series(x1)); case 2L: return(-Cos_Series(x1)); case 3L: return(Sin_Series(x1)); default: throw new InvalidOperationException(); } }
private static DoubleDouble LogGamma_Asymptotic(DoubleDouble x) { // Sum from smallest to largest terms to minimize error. return(BernoulliSum(x) + halfLogTwoPi - x + (x - 0.5) * DoubleDouble.Log(x)); }
private static DoubleDouble LogGammaTwoPlus(DoubleDouble y) { return((DoubleDouble.One - AdvancedDoubleDoubleMath.EulerGamma) * y + ZetaSeries(y)); }
private static DoubleDouble LogGammaOnePlus(DoubleDouble y) { return(LogGammaTwoPlus(y) - DoubleDouble.Log1P(y)); }