/// <summary> /// Calulates the ratio of the count of positive to negative values. /// The test succeeds if the ratio approaches unity as the sample size approaches infinity /// </summary> /// <param name="samples">The sample count</param> public static double SignRatio(IPolyrand random, long samples, long radius) { var domain = closed(0 - math.abs(radius), 0 + math.abs(radius)); var pos = 0L; var neg = 0L; var zed = 0L; for (var i = 0; i < samples; i++) { var next = random.Next(domain); if (next > 0) { pos++; } else if (next < 0) { neg++; } else { zed++; } } var ratio = (neg != 0 ? (double)pos / (double)neg : 0d); // Should be zero or extremly close so combining it with the ratio should have // negligible impact. Otherwise, something is wrong and willb reflected in the // metric var eps = (double)zed / (double)samples; var metric = ratio + eps; return(metric.Round(6)); }
/// <summary> /// Shuffles array content in-place /// </summary> /// <param name="random">The random source</param> /// <param name="src">The input/output array</param> /// <typeparam name="T">The element type</typeparam> public static T[] Shuffle <T>(this IPolyrand random, T[] src) { for (int i = 0; i < src.Length; i++) { swap(ref src[i], ref src[i + random.Next(0, src.Length - i)]); } return(src); }
static IEnumerable <T> UnfilteredStream <T>(this IPolyrand src, Interval <T> domain) where T : struct { while (true) { yield return(src.Next <T>(domain.Left, domain.Right)); } }
/// <summary> /// Produces a random stream of unfiltered/unbounded points from a source /// </summary> /// <param name="random">The point source</param> /// <typeparam name="T">The point type</typeparam> public static IRandomStream <T> Stream <T>(this IPolyrand random) where T : struct { IEnumerable <T> produce() { while (true) { yield return(random.Next <T>()); } } return(stream(produce(), random.RngKind)); }
public static void Shuffle <T>(IList <T> list, IPolyrand random = null) { int n = list.Count; // Algorithm: repeatedly draw random integers, without replacement. // We fill in the array from back to front. // (would also work the other way) for (int i = n - 1; i > 0; i--) { int j = random?.Next(i + 1) ?? Rand.Int(i + 1); T temp = list[i]; list[i] = list[j]; list[j] = temp; } }
/// <summary> /// Produces a random stream of bytes /// </summary> /// <param name="random">The random source</param> public static IRandomStream <byte> Bytes(this IPolyrand random) { IEnumerable <byte> produce() { while (true) { var bytes = BitConverter.GetBytes(random.Next <ulong>()); for (var i = 0; i < bytes.Length; i++) { if (i == 0) { yield return(bytes[i]); } } } } return(stream(produce(), random.RngKind)); }
internal static HashSet <int> SampleWithoutReplacement(int itemCount, int count, IPolyrand random = null) { if (count > itemCount) { throw new ArgumentException("count > itemCount"); } HashSet <int> set = new HashSet <int>(); if (count > itemCount / 2) { // use Shuffle int[] array = Util.ArrayInit(itemCount, i => i); Shuffle(array, random); for (int i = 0; i < count; i++) { set.Add(array[i]); } } else { // use rejection for (int i = 0; i < count; i++) { while (true) { int item = random?.Next(itemCount) ?? Rand.Int(itemCount); if (!set.Contains(item)) { set.Add(item); break; } } } } return(set); }
public static BitVector16 BitVector16(this IPolyrand random) => random.Next <ushort>();
public static double Next(this IPolyrand src, double min, double max, bool truncate = false) => truncate?Math.Floor(src.Next(min, max)) : src.Next(min, max);
public static float Next(this IPolyrand src, float min, float max, bool truncate = false) => truncate?MathF.Floor(src.Next(min, max)) : src.Next(min, max);
public static BitString BitString(this IPolyrand random, int minlen, int maxlen) => random.BitString(random.Next <int>(minlen, maxlen + 1));
public static BitVector64 BitVector64(this IPolyrand random) => random.Next <ulong>();
public static int Int(int maxPlus1, IPolyrand random = null) { return(random?.Next(maxPlus1) ?? gen.Next(maxPlus1)); }
public static BitMatrix4 BitMatrix(this IPolyrand random, N4 n4) => Z0.BitMatrix4.Define(random.Next <ushort>());
static double NextDouble(IPolyrand random) => random?.Next <double>() ?? gen.NextDouble();
static IEnumerable <T> FilteredStream <T>(this IPolyrand src, Interval <T> domain, Func <T, bool> filter) where T : struct { var next = default(T); var tries = 0; var tryMax = 10; while (true) { if (typeof(T) == typeof(sbyte)) { next = generic <T>(src.Next <sbyte>(domain.As <sbyte>())); } else if (typeof(T) == typeof(byte)) { next = generic <T>(src.Next <byte>(domain.As <byte>())); } else if (typeof(T) == typeof(short)) { next = generic <T>(src.Next <short>(domain.As <short>())); } else if (typeof(T) == typeof(ushort)) { next = generic <T>(src.Next <ushort>(domain.As <ushort>())); } else if (typeof(T) == typeof(int)) { next = generic <T>(src.Next <int>(domain.As <int>())); } else if (typeof(T) == typeof(uint)) { next = generic <T>(src.Next <uint>(domain.As <uint>())); } else if (typeof(T) == typeof(long)) { next = generic <T>(src.Next <long>(domain.As <long>())); } else if (typeof(T) == typeof(ulong)) { next = generic <T>(src.Next <ulong>(domain.As <ulong>())); } else if (typeof(T) == typeof(float)) { next = generic <T>(src.Next <float>(domain.As <float>())); } else if (typeof(T) == typeof(double)) { next = generic <T>(src.Next <double>(domain.As <double>())); } else { throw unsupported <T>(); } if (filter(next)) { tries = 0; yield return(next); } else { ++tries; if (tries > tryMax) { throw new Exception($"Filter too rigid over {domain}; last failed value: {next}"); } } } }
public static BitVector8 BitVector8(this IPolyrand random) => random.Next <byte>();
public static UInt4 NextUInt4(this IPolyrand src, Interval <byte>?domain = null) { return(domain.Map(d => (UInt4)src.Next(d.Left, d.Right), () => (UInt4)src.Next <byte>())); }
public static BitVector16 BitVector(this IPolyrand random, N16 n, int?maxwidth = null) { var v = random.Next <ushort>(); return(maxwidth == null ? v : (v >>= (16 - maxwidth))); }
public static BitMatrix8 BitMatrix(this IPolyrand random, N8 n) => Z0.BitMatrix8.From(random.Next <ulong>());
public static BitVector16 BitVector16(this IPolyrand random, int maxwidth) { var v = random.Next <ushort>(); return(v >>= (16 - maxwidth)); }
public static BitVector32 BitVector32(this IPolyrand random) => random.Next <uint>();
public double Sample(IPolyrand random) => Math.Pow(random.Next <double>(), -1.0 / Shape) * LowerBound;
static int NextInt(int max, IPolyrand random) => random?.Next(max) ?? gen.Next(max);