using System; using System.Numerics; namespace FastRng; /// /// Provides some mathematical function, which are not available within in .NET itself. /// public static class FloatingPointMathTools where TNum : IFloatingPointIeee754, IAdditionOperators { private static readonly TNum SQRT_2 = TNum.Sqrt(TNum.One + TNum.One); private static readonly TNum SQRT_PI = TNum.Sqrt(TNum.Pi); // Source: http://rosettacode.org/wiki/Gamma_function#Go private static readonly TNum F1 = TNum.CreateChecked(6.5f); private static readonly TNum A1 = TNum.CreateChecked(.99999999999980993f); private static readonly TNum A2 = TNum.CreateChecked(676.5203681218851f); private static readonly TNum A3 = TNum.CreateChecked(1259.1392167224028f); private static readonly TNum A4 = TNum.CreateChecked(771.32342877765313f); private static readonly TNum A5 = TNum.CreateChecked(176.61502916214059f); private static readonly TNum A6 = TNum.CreateChecked(12.507343278686905f); private static readonly TNum A7 = TNum.CreateChecked(.13857109526572012f); private static readonly TNum A8 = TNum.CreateChecked(9.9843695780195716e-6f); private static readonly TNum A9 = TNum.CreateChecked(1.5056327351493116e-7f); private static readonly TNum CONST1 = TNum.One; private static readonly TNum CONST2 = CONST1 + TNum.One; private static readonly TNum CONST3 = CONST2 + TNum.One; private static readonly TNum CONST4 = CONST3 + TNum.One; private static readonly TNum CONST5 = CONST4 + TNum.One; private static readonly TNum CONST6 = CONST5 + TNum.One; private static readonly TNum CONST7 = CONST6 + TNum.One; private static readonly TNum CONST_HALF = TNum.CreateChecked(0.5f); /// /// The mathematical gamma function. /// /// The value for which you want calculate gamma. public static TNum Gamma(TNum z) { // Source: http://rosettacode.org/wiki/Gamma_function#Go var t = z + F1; var x = A1 + A2 / z - A3 / (z + CONST1) + A4 / (z + CONST2) - A5 / (z + CONST3) + A6 / (z + CONST4) - A7 / (z + CONST5) + A8 / (z + CONST6) + A9 / (z + CONST7); return SQRT_2 * SQRT_PI * TNum.Pow(t, z - CONST_HALF) * TNum.Exp(-t) * x; } /// /// The mathematical factorial function for floating-point numbers. /// /// The value, for which you want to know the factorial. public static TNum Factorial(TNum x) => Gamma(x + CONST1); }