|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// https://www.johndcook.com/blog/csharp_phi/
|
|
|
|
/// Source: https://www.johndcook.com/blog/csharp_phi/
|
|
|
|
/// </summary>
|
|
|
|
static float NormalCdf(float x) |
|
|
|
{ |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// https://www.johndcook.com/blog/csharp_phi_inverse/
|
|
|
|
/// Source: https://www.johndcook.com/blog/csharp_phi_inverse/
|
|
|
|
/// </summary>
|
|
|
|
static float RationalApproximation(float t) |
|
|
|
{ |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// https://www.johndcook.com/blog/csharp_phi_inverse/
|
|
|
|
/// Source: https://www.johndcook.com/blog/csharp_phi_inverse/
|
|
|
|
/// Note: generates NaN values for values 0 and 1
|
|
|
|
/// <param name="probability">Must be with the range (0, 1)</param>
|
|
|
|
static float NormalCdfInverse(float probability) |
|
|
|
/// <param name="uniformSample">A uniform sample value between the range (0, 1)</param>
|
|
|
|
static float NormalCdfInverse(float uniformSample) |
|
|
|
if (probability <= 0f || probability >= 1.0f) |
|
|
|
throw new ArgumentOutOfRangeException($"Probability {probability} is outside the range (0, 1)"); |
|
|
|
|
|
|
|
return probability < 0.5f |
|
|
|
? -RationalApproximation(math.sqrt(-2.0f * math.log(probability))) |
|
|
|
: RationalApproximation(math.sqrt(-2.0f * math.log(1.0f - probability))); |
|
|
|
return uniformSample < 0.5f |
|
|
|
? -RationalApproximation(math.sqrt(-2.0f * math.log(uniformSample))) |
|
|
|
: RationalApproximation(math.sqrt(-2.0f * math.log(1.0f - uniformSample))); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
public static float TruncatedNormalSample(float u, float min, float max, float mean, float stdDev) |
|
|
|
/// <param name="uniformSample">A sample value between 0 and 1 generated from a uniform distribution</param>
|
|
|
|
/// <param name="min">The minimum possible value to generate</param>
|
|
|
|
/// <param name="max">The maximum possible value to generate</param>
|
|
|
|
/// <param name="mean">The mean of the normal distribution</param>
|
|
|
|
/// <param name="stdDev">The standard deviation of the normal distribution</param>
|
|
|
|
/// <returns>A value sampled from a truncated normal distribution</returns>
|
|
|
|
/// <exception cref="ArgumentException"></exception>
|
|
|
|
public static float TruncatedNormalSample(float uniformSample, float min, float max, float mean, float stdDev) |
|
|
|
if (u == 0f) |
|
|
|
if (uniformSample == 0f) |
|
|
|
if (u == 1f) |
|
|
|
if (uniformSample == 1f) |
|
|
|
return max; |
|
|
|
if (stdDev == 0f) |
|
|
|
return math.clamp(mean, min, max); |
|
|
|
|
|
|
var c = math.lerp(a, b, u); |
|
|
|
var c = math.lerp(a, b, uniformSample); |
|
|
|
|
|
|
|
if (c == 0f) |
|
|
|
return max; |
|
|
|