From 4b8723d194c1bef0c93a492e446998760292f558 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 29 Sep 2020 19:49:18 +0200 Subject: [PATCH] Added a shape fitter --- FastRng/Double/ShapeFitter.cs | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 FastRng/Double/ShapeFitter.cs diff --git a/FastRng/Double/ShapeFitter.cs b/FastRng/Double/ShapeFitter.cs new file mode 100644 index 0000000..6e0fa1d --- /dev/null +++ b/FastRng/Double/ShapeFitter.cs @@ -0,0 +1,43 @@ +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace FastRng.Double +{ + public sealed class ShapeFitter + { + private readonly double[] probabilities; + private readonly double[] samples; + private readonly IRandom rng; + private readonly ushort sampleSize; + + public ShapeFitter(Func shapeFunction, IRandom rng, ushort sampleSize = 100) + { + this.rng = rng; + this.sampleSize = sampleSize; + this.samples = new double[sampleSize]; + this.probabilities = new double[sampleSize]; + + var sampleStepSize = 1.0 / sampleSize; + var nextStep = 0.0 + sampleStepSize; + for (var n = 0; n < sampleSize; n++) + { + this.probabilities[n] = shapeFunction(nextStep); + nextStep += sampleStepSize; + } + } + + public async ValueTask NextNumber() + { + while (true) + { + var nextNumber = await this.rng.GetUniform(); + var nextBucket = (int)Math.Floor(nextNumber * this.sampleSize); + this.samples[nextBucket] += this.probabilities[nextBucket]; + + if (this.samples[nextBucket] >= 1.0) + return nextNumber; + } + } + } +} \ No newline at end of file