2 using System.Collections.Generic;
6 namespace droid.Runtime.Utilities.Sampling {
47 Distributions.DirectionE d = Distributions.DirectionE.Left_) {
48 this._de = distribution_enum;
49 _conf_level = Distributions.ConfidenceLevel._95;
61 public float Range(
float min,
float max) {
64 return Random.Range(min, max);
66 return Distributions.RandomRangeNormalDistribution(min, max, this._conf_level);
68 return Distributions.RandomRangeSlope(min, max, this._factor, this._Direction);
70 return Distributions.RandomRangeExponential(min, max, this._factor, this._Direction);
72 return Distributions.RandomLinear(_factor);
74 return Random.Range(min, max);
81 public static class Distributions {
86 public enum ConfidenceLevel {
103 public enum DirectionE {
108 static float[] _confidence_to_z_score = {
141 public static float RandomRangeNormalDistribution(
float min,
144 confidence_level_cutoff ) {
145 var mean = 0.5f * (min + max);
148 var z_score_cutoff = _confidence_to_z_score[(int)confidence_level_cutoff];
150 var new_width = (max - min) / 2.0f;
151 var sigma = new_width / z_score_cutoff;
154 float random_normal_num;
156 random_normal_num = RandomNormalDistribution(mean, sigma);
157 }
while (random_normal_num > max || random_normal_num < min);
160 return random_normal_num;
176 public static float RandomNormalDistribution(
float mean,
float std_dev) {
178 var random_normal_num = RandomFromStandardNormalDistribution();
181 random_normal_num *= std_dev;
184 random_normal_num += mean;
187 return random_normal_num;
197 public static float RandomFromStandardNormalDistribution() {
208 u =
Random.Range(-1f, 1f);
209 v =
Random.Range(-1f, 1f);
211 }
while (!(s != 0 && s < 1));
216 if (
Random.Range(0, 2) == 0) {
223 var z = seed * Mathf.Sqrt(-2.0f * Mathf.Log(s) / s);
233 public static float RandomRangeSlope(
float min,
float max,
float skew, DirectionE direction) {
234 return min + RandomFromSlopedDistribution(skew, direction) * (max - min);
242 public static float RandomFromSlopedDistribution(
float skew, DirectionE direction) {
247 var max_x = Inverse_Sec_Sqrd(max_y);
249 var max_cdf = Sec_Sqrd_CumulativeDistributionFunction(max_x);
251 var u =
Random.Range(0.0f, max_cdf);
252 var x_val = Sec_Sqrd_InverseCumulativeDistributionFunction(u);
255 var value = x_val / max_x;
257 if (direction == DirectionE.Left_) {
258 value = 1.0f - value;
270 static float Inverse_Sec_Sqrd(
float y) {
274 return Mathf.Acos(1.0f / Mathf.Sqrt(y));
278 static float Sec_Sqrd_CumulativeDistributionFunction(
float x) {
285 static float Sec_Sqrd_InverseCumulativeDistributionFunction(
float x) {
289 return Mathf.Atan(x);
297 public static float RandomRangeLinear(
float min,
float max,
float slope) {
299 return Random.Range(min, max);
302 var val = RandomLinear(slope);
304 return min + (max - min) * val;
308 public static float RandomLinear(
float slope) {
309 var abs_value = RandomFromLinearWithPositiveSlope(Mathf.Abs(slope));
311 return 1 - abs_value;
318 static float RandomFromLinearWithPositiveSlope(
float slope) {
320 return Random.Range(0.0f, 1.0f);
325 x =
Random.Range(0.0f, 1.0f);
326 y =
Random.Range(0.0f, 1.0f);
328 y -= (1 - slope) / 2.0f;
330 }
while (y > x * slope);
350 public static float RandomRangeExponential(
float min,
float max,
float exponent, DirectionE direction) {
351 return min + RandomFromExponentialDistribution(exponent, direction) * (max - min);
363 public static float RandomFromExponentialDistribution(
float exponent, DirectionE direction) {
365 var max_cdf = ExponentialRightCdf(1.0f, exponent);
367 var u =
Random.Range(0.0f, max_cdf);
368 var x_val = EponentialRightInverseCdf(u, exponent);
370 if (direction == DirectionE.Left_) {
371 x_val = 1.0f - x_val;
378 static float ExponentialRightInverse(
float y,
float exponent) {
return Mathf.Pow(y, 1.0f / exponent); }
381 static float ExponentialRightCdf(
float x,
float exponent) {
382 var integral_exp = exponent + 1.0f;
383 return Mathf.Pow(x, integral_exp) / integral_exp;
387 static float EponentialRightInverseCdf(
float x,
float exponent) {
388 var integral_exp = exponent + 1.0f;
389 return Mathf.Pow(integral_exp * x, 1.0f / integral_exp);
405 public static int RandomChoiceFollowingDistribution(List<float> probabilities) {
407 var cdf =
new float[probabilities.Count];
409 for (var i = 0; i < probabilities.Count; ++i) {
410 cdf[i] = sum + probabilities[i];
415 var cdf_value =
Random.Range(0.0f, cdf[probabilities.Count - 1]);
416 var index = Array.BinarySearch(cdf, cdf_value);
Distributions.DirectionE _Direction
Distributions.ConfidenceLevel _conf_level
DistributionSampler(DistributionEnum distribution_enum=DistributionEnum.Uniform_, Distributions.DirectionE d=Distributions.DirectionE.Left_)
float Range(float min, float max)