/// <summary> /// Randomly permute the specified number of elements in the supplied /// array starting at the specified index. /// </summary> public static void Randomize <T>( this IRandomUniform rnd, T[] array, long start, long count) { for (long i = start, e = start + count; i < e; i++) { array.Swap(i, start + rnd.UniformLong(count)); } }
/// <summary> /// Returns a uniform long which is guaranteed not to be zero. /// </summary> public static long UniformLongNonZero(this IRandomUniform rnd) { long r; do { r = rnd.UniformLong(); } while (r == 0); return(r); }
/// <summary> /// Creates an unordered array of subsetCount long indices that /// constitute a subset of all longs in the range [0, count-1]. /// O(subsetCount) for subsetCount << count. /// NOTE: It is assumed that subsetCount is significantly smaller /// than count. If this is not the case, use /// CreateRandomSubsetOfSize instead. /// WARNING: As subsetCount approaches count execution time /// increases significantly. /// </summary> public static long[] CreateSmallRandomSubsetIndexArrayLong( this IRandomUniform rnd, long subsetCount, long count) { Requires.That(subsetCount >= 0 && subsetCount <= count); var subsetIndices = new LongSet(subsetCount); for (int i = 0; i < subsetCount; i++) { long index; do { index = rnd.UniformLong(count); }while (!subsetIndices.TryAdd(index)); } return(subsetIndices.ToArray()); }
/// <summary> /// Randomly permute the first count elements of the /// supplied array. This does work with counts of up /// to about 2^50. /// </summary> public static void Randomize <T>( this IRandomUniform rnd, T[] array, long count) { if (count <= (long)int.MaxValue) { int intCount = (int)count; for (int i = 0; i < intCount; i++) { array.Swap(i, rnd.UniformInt(intCount)); } } else { for (long i = 0; i < count; i++) { array.Swap(i, rnd.UniformLong(count)); } } }
/// <summary> /// Creates an unordered array of subsetCount long indices that /// constitute a subset of all longs in the range [0, count-1]. /// O(subsetCount) for subsetCount << count. /// NOTE: It is assumed that subsetCount is significantly smaller /// than count. If this is not the case, use /// CreateRandomSubsetOfSize instead. /// WARNING: As subsetCount approaches count execution time /// increases significantly. /// </summary> public static long[] CreateSmallRandomSubsetIndexArrayLong( this IRandomUniform rnd, long subsetCount, long count) { if (!(subsetCount >= 0 && subsetCount <= count)) { throw new ArgumentOutOfRangeException(nameof(subsetCount)); } var subsetIndices = new LongSet(subsetCount); for (int i = 0; i < subsetCount; i++) { long index; do { index = rnd.UniformLong(count); }while (!subsetIndices.TryAdd(index)); } return(subsetIndices.ToArray()); }