FastRng/FastRng/Float/MathTools.cs

83 lines
3.2 KiB
C#

using System;
namespace FastRng.Float
{
/// <summary>
/// Provides some mathematical function, which are not available within in the .NET framework.
/// </summary>
public static class MathTools
{
private static readonly float SQRT_2 = MathF.Sqrt(2.0f);
private static readonly float SQRT_PI = MathF.Sqrt(MathF.PI);
/// <summary>
/// The mathematical gamma function.
/// </summary>
/// <param name="z">The value for which you want calculate gamma.</param>
public static float Gamma(float z)
{
// Source: http://rosettacode.org/wiki/Gamma_function#Go
const float F1 = 6.5f;
const float A1 = .99999999999980993f;
const float A2 = 676.5203681218851f;
const float A3 = 1259.1392167224028f;
const float A4 = 771.32342877765313f;
const float A5 = 176.61502916214059f;
const float A6 = 12.507343278686905f;
const float A7 = .13857109526572012f;
const float A8 = 9.9843695780195716e-6f;
const float A9 = 1.5056327351493116e-7f;
var t = z + F1;
var x = A1 +
A2 / z -
A3 / (z + 1) +
A4 / (z + 2) -
A5 / (z + 3) +
A6 / (z + 4) -
A7 / (z + 5) +
A8 / (z + 6) +
A9 / (z + 7);
return MathTools.SQRT_2 * MathTools.SQRT_PI * MathF.Pow(t, z - 0.5f) * MathF.Exp(-t) * x;
}
/// <summary>
/// The mathematical factorial function for floating-point numbers.
/// </summary>
/// <param name="x">The value, for which you want to know the factorial.</param>
public static float Factorial(float x) => MathTools.Gamma(x + 1.0f);
/// <summary>
/// The mathematical factorial function for integer numbers.
/// </summary>
/// <param name="x">The value, for which you want to know the factorial.</param>
/// <exception cref="ArgumentOutOfRangeException">Throws, when x is greater than 20. Due to limitations of 64bit ulong type.</exception>
public static ulong Factorial(uint x)
{
if (x > 20)
throw new ArgumentOutOfRangeException(nameof(x), $"Cannot compute {x}!, since ulong.max is 18_446_744_073_709_551_615.");
ulong accumulator = 1;
for (uint factor = 1; factor <= x; factor++)
accumulator *= factor;
return accumulator;
}
/// <summary>
/// The mathematical factorial function for integer numbers.
/// </summary>
/// <param name="x">The value, for which you want to know the factorial.</param>
/// <exception cref="ArgumentOutOfRangeException">Throws, when x is greater than 20. Due to limitations
/// of 64bit ulong type. Throws also, when x is less than 0.</exception>
public static ulong Factorial(int x)
{
if(x < 0)
throw new ArgumentOutOfRangeException(nameof(x), "Given value must be greater as zero.");
return MathTools.Factorial((uint) x);
}
}
}