Ejemplo n.º 1
0
 public HaltonRandomSeries(
     int haltonCount, IRandomUniform randomUniform)
 {
     m_haltonStateArray = new double[haltonCount].SetByIndex(
         i => randomUniform.UniformDouble());
     m_randomUniform = randomUniform;
 }
Ejemplo n.º 2
0
        public static V2d UniformV2dDirection(this IRandomUniform rnd)
        {
            double phi = rnd.UniformDouble() * Constant.PiTimesTwo;

            return(new V2d(System.Math.Cos(phi),
                           System.Math.Sin(phi)));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns a random subset of the enumeration with a supplied number of
        /// elements (subsetCount). The elements in the subset are in the
        /// same order as in the input. O(count).
        /// NOTE: The number of elements of the Enumerable need to be calculated, in case of true enumerations
        ///       the implementation of .Count() results in a second evaluation of the enumerable.
        /// </summary>
        public static T[] CreateRandomSubsetOfSize <T>(
            this IEnumerable <T> input, long subsetCount, IRandomUniform rnd = null)
        {
            if (rnd == null)
            {
                rnd = new RandomSystem();
            }
            long count = input.Count();

            if (!(subsetCount >= 0 && subsetCount <= count))
            {
                throw new ArgumentOutOfRangeException(nameof(subsetCount));
            }
            var  subset = new T[subsetCount];
            long si = 0, ai = 0;

            foreach (var a in input)
            {
                if (ai < count && si < subsetCount)
                {
                    var p = (double)(subsetCount - si) / (double)(count - ai++);
                    if (rnd.UniformDouble() <= p)
                    {
                        subset[si++] = a;
                    }
                }
                else
                {
                    break;
                }
            }
            return(subset);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns a random subset of an array with a supplied number of
        /// elements (subsetCount). The elements in the subset are in the
        /// same order as in the original array. O(count).
        /// NOTE: this method needs to generate one random number for each
        /// element of the original array. If subsetCount is significantly
        /// smaller than count, it is more efficient to use
        /// <see cref="CreateSmallRandomSubsetIndexArray"/> or
        /// <see cref="CreateSmallRandomSubsetIndexArrayLong"/> or
        /// <see cref="CreateSmallRandomOrderedSubsetIndexArray"/> or
        /// <see cref="CreateSmallRandomOrderedSubsetIndexArrayLong"/>.
        /// </summary>
        public static T[] CreateRandomSubsetOfSize <T>(
            this T[] array, long subsetCount, IRandomUniform rnd = null)
        {
            if (rnd == null)
            {
                rnd = new RandomSystem();
            }
            long count = array.LongLength;

            if (!(subsetCount >= 0 && subsetCount <= count))
            {
                throw new ArgumentOutOfRangeException(nameof(subsetCount));
            }
            var  subset = new T[subsetCount];
            long si     = 0;

            for (int ai = 0; ai < count && si < subsetCount; ai++)
            {
                var p = (double)(subsetCount - si) / (double)(count - ai);
                if (rnd.UniformDouble() <= p)
                {
                    subset[si++] = array[ai];
                }
            }
            return(subset);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Returns a fully uniformly distributed vector (corresponds to a
        /// uniformly distributed point on the surface of the unit sphere).
        /// Note however, that the returned vector will never be equal to
        /// [0, 0, -1].
        /// </summary>
        public static V3d UniformV3dFullDirection(this IRandomUniform rnd)
        {
            double phi = rnd.UniformDoubleFull() * Constant.PiTimesTwo;
            double z   = 1.0 - rnd.UniformDoubleFull() * 2.0;
            double s   = System.Math.Sqrt(1.0 - z * z);

            return(new V3d(System.Math.Cos(phi) * s, System.Math.Sin(phi) * s, z));
        }
Ejemplo n.º 6
0
 /// <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));
     }
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates an array that contains a random permutation of the
        /// numbers in the interval [0, count-1].
        /// </summary>
        public static long[] CreatePermutationArrayLong(
            this IRandomUniform rnd, long count)
        {
            var p = new long[count].SetByIndexLong(i => i);

            rnd.Randomize(p);
            return(p);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Creates an array that contains a random permutation of the
        /// ints in the interval [0, count-1].
        /// </summary>
        public static int[] CreatePermutationArray(
            this IRandomUniform rnd, int count)
        {
            var p = new int[count].SetByIndex(i => i);

            rnd.Randomize(p);
            return(p);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Create a random array of full doubles in the half-open interval
        /// [0.0, 1.0) of the specified length.
        /// </summary>
        public static double[] CreateUniformDoubleFullArray(
            this IRandomUniform rnd, long length)
        {
            var array = new double[length];

            rnd.FillUniformFull(array);
            return(array);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Create a random array of floats in the half-open interval
        /// [0.0, 1.0) of the specified length.
        /// </summary>
        public static float[] CreateUniformFloatArray(
            this IRandomUniform rnd, long length)
        {
            var array = new float[length];

            rnd.FillUniform(array);
            return(array);
        }
Ejemplo n.º 11
0
 /// <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, int start, int count)
 {
     for (int i = start, e = start + count; i < e; i++)
     {
         array.Swap(i, start + rnd.UniformInt(count));
     }
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Creates an ordered array of subsetCount int indices that
        /// constitute a subset of all ints in the range [0, count-1].
        /// O(subsetCount * log(subsetCount)) for subsetCount &lt;&lt; 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 int[] CreateSmallRandomOrderedSubsetIndexArray(
            this IRandomUniform rnd, int subsetCount, int count)
        {
            var subsetIndexArray = rnd.CreateSmallRandomSubsetIndexArray(subsetCount, count);

            subsetIndexArray.QuickSortAscending();
            return(subsetIndexArray);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Creates an ordered array of subsetCount long indices that
        /// constitute a subset of all longs in the range [0, count-1].
        /// O(subsetCount * log(subsetCount)) for subsetCount &lt;&lt; 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[] CreateSmallRandomOrderedSubsetIndexArrayLong(
            this IRandomUniform rnd, long subsetCount, long count)
        {
            var subsetIndexArray = rnd.CreateSmallRandomSubsetIndexArrayLong(subsetCount, count);

            subsetIndexArray.QuickSortAscending();
            return(subsetIndexArray);
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Randomly permute the specified number of elements in the supplied
 /// list starting at the specified index.
 /// </summary>
 public static void Randomize <T>(
     this IRandomUniform rnd, List <T> list, int start, int count)
 {
     for (int i = start; i < start + count; i++)
     {
         list.Swap(i, start + rnd.UniformInt(count));
     }
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Fills the specified array with random floats in the half-open
        /// interval [0.0f, 1.0f).
        /// </summary>
        public static void FillUniform(this IRandomUniform rnd, float[] array)
        {
            long count = array.LongLength;

            for (long i = 0; i < count; i++)
            {
                array[i] = rnd.UniformFloat();
            }
        }
Ejemplo n.º 16
0
        /// <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);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Returns a uniform int which is guaranteed not to be zero.
        /// </summary>
        public static int UniformIntNonZero(this IRandomUniform rnd)
        {
            int r;

            do
            {
                r = rnd.UniformInt();
            } while (r == 0);
            return(r);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Generates normal distributed random variable with given mean and standard deviation.
        /// Uses the Box-Muller Transformation to transform two uniform distributed random variables to one normal distributed value.
        /// NOTE: If multiple normal distributed random values are required, consider using <see cref="RandomGaussian"/>.
        /// </summary>
        public static double Gaussian(this IRandomUniform rnd, double mean = 0.0, double stdDev = 1.0)
        {
            // Box-Muller Transformation
            var u1            = 1.0 - rnd.UniformDouble(); // uniform (0,1] -> log requires > 0
            var u2            = rnd.UniformDouble();       // uniform [0,1)
            var randStdNormal = Fun.Sqrt(-2.0 * Fun.Log(u1)) *
                                Fun.Sin(Constant.PiTimesTwo * u2);

            return(mean + stdDev * randStdNormal);
        }
Ejemplo n.º 19
0
 /// <summary>
 /// Create a ForcedRandomSeries with the given sample sequence and the seed as offset.
 /// The sequence is supposed to contain NxN points in random order.
 /// </summary>
 public ForcedRandomSeries(V2i[] series, int matrixSize, IRandomUniform rnd, bool jitter = true)
 {
     m_series     = series;
     m_matrixSize = matrixSize;
     m_norm       = 1.0 / m_matrixSize; // [0, 1)
     m_rnd        = rnd;
     m_jitter     = jitter;
     // random offset of sample pattern
     m_seed = new V2i(rnd.UniformInt(m_matrixSize), rnd.UniformInt(m_matrixSize));
 }
Ejemplo n.º 20
0
        /// <summary>
        /// Randomly permute the elements of the supplied list.
        /// </summary>
        public static void Randomize <T>(
            this IRandomUniform rnd, List <T> list)
        {
            int count = list.Count;

            for (int i = 0; i < count; i++)
            {
                list.Swap(i, rnd.UniformInt(count));
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Creates clusters for all points which are within an epsilon
        /// distance from each other. This algorithm uses a hash-grid and
        /// only works fast if the supplied epsilon is small enough that
        /// not too many points fall within each cluster. Thus it is ideal
        /// for merging vertices in meshes and point sets, that are different
        /// due to numerical inaccuracies.
        /// </summary>
        public PointEpsilonClustering(V3d[] pa, double epsilon, IRandomUniform rnd = null)
        {
            rnd = rnd ?? new RandomSystem();
            var count = pa.Length;

            Alloc(count);
            var ca = m_indexArray;
            var dict = new IntDict <int>(count, stackDuplicateKeys: true);
            int rndBits = 0; int bit = 0;
            var ha   = new int[8];
            var eps2 = epsilon * epsilon;

            for (int i = 0; i < count; i++)
            {
                var p  = pa[i]; p.HashCodes8(epsilon, ha);
                int ci = ca[i]; if (ca[ci] != ci)
                {
                    do
                    {
                        ci = ca[ci];
                    } while (ca[ci] != ci); ca[i] = ci;
                }
                for (int hi = 0; hi < 8; hi++)
                {
                    foreach (var j in dict.ValuesWithKey(ha[hi]))
                    {
                        int cj = ca[j]; if (ca[cj] != cj)
                        {
                            do
                            {
                                cj = ca[cj];
                            } while (ca[cj] != cj); ca[j] = cj;
                        }
                        if (ci == cj || V3d.DistanceSquared(p, pa[j]) >= eps2)
                        {
                            continue;
                        }
                        bit >>= 1; if (bit == 0)
                        {
                            rndBits = rnd.UniformInt(); bit = 1 << 30;
                        }
                        if ((rndBits & bit) != 0)
                        {
                            ca[ci] = cj; ca[i] = cj; ci = cj;
                        }
                        else
                        {
                            ca[cj] = ci; ca[j] = ci;
                        }
                    }
                }
                dict[ha[0]] = i;
            }
            Init();
        }
Ejemplo n.º 22
0
 /// <summary>
 /// Returns a uniformly distributed int in the interval [0, count-1].
 /// In order to avoid excessive aliasing, two random numbers are used
 /// when count is greater or equal 2^24 and the random generator
 /// delivers 32 random bits or less. The method thus works fairly
 /// decently for all integers.
 /// </summary>
 public static int UniformInt(this IRandomUniform rnd, int size)
 {
     if (rnd.GeneratesFullDoubles || size < 16777216)
     {
         return((int)(rnd.UniformDouble() * size));
     }
     else
     {
         return((int)(rnd.UniformDoubleFull() * size));
     }
 }
Ejemplo n.º 23
0
 /// <summary>
 /// Returns a uniformly distributed long in the interval [0, size-1].
 /// NOTE: If count has more than about 48 bits, aliasing leads to
 /// noticeable (greater 5%) shifts in the probabilities (i.e. one
 /// long has a probability of x and the other a probability of
 /// x * (2^(52-b)-1)/(2^(52-b)), where b is log(size)/log(2)).
 /// </summary>
 public static long UniformLong(this IRandomUniform rnd, long size)
 {
     if (rnd.GeneratesFullDoubles || size < 16777216)
     {
         return((long)(rnd.UniformDouble() * size));
     }
     else
     {
         return((long)(rnd.UniformDoubleFull() * size));
     }
 }
Ejemplo n.º 24
0
        /// <summary>
        /// Returns a uniformly distributed double in the closed interval
        /// [0.0, 1.0]. Note, that two random values are used to make all 53
        /// bits random.
        /// </summary>
        public static double UniformDoubleFullClosed(this IRandomUniform rnd)
        {
            if (rnd.GeneratesFullDoubles)
            {
                return(rnd.UniformDoubleClosed());
            }
            long r = ((~0xfL & (long)rnd.UniformInt()) << 22)
                     | ((long)rnd.UniformInt() >> 5);

            return(r * (1.0 / 9007199254740991.0));
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Enumerates elements in random order.
        /// </summary>
        public static IEnumerable <T> RandomOrder <T>(this IEnumerable <T> self, IRandomUniform rnd = null)
        {
            var tmp = self.ToArray();

            if (rnd == null)
            {
                rnd = new RandomSystem();
            }
            var perm = rnd.CreatePermutationArray(tmp.Length);

            return(perm.Select(index => tmp[index]));
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Uniform vector in the closed unit sphere (i.e vectors to
        /// the surface of the sphere may be generated).
        /// </summary>
        public static V3d UniformV3dClosedSphere(this IRandomUniform rnd)
        {
            double r2;
            V3d    p;

            do
            {
                p  = (rnd.UniformV3dClosed() + c_shift) * 2.0;
                r2 = p.LengthSquared;
            }while (r2 > 1.0);
            return(p);
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Merge clusters of exactly equal points. The supplied epsilon is used to define a
        /// grid as acceleration data structure and the algorithm is only fast if not too many
        /// points fall within the supplied epsilon.
        /// </summary>
        public PointEqualClustering(V3d[] pa, double eps, IRandomUniform rnd = null)
        {
            rnd = rnd ?? new RandomSystem();
            var count = pa.Length;

            Alloc(count);
            var ca = m_indexArray;
            var dict = new IntDict <int>(count, stackDuplicateKeys: true);
            int rndBits = 0; int bit = 0;

            for (int i = 0; i < count; i++)
            {
                var p = pa[i]; var hc = p.HashCode1(eps);
                int ci = ca[i]; if (ca[ci] != ci)
                {
                    do
                    {
                        ci = ca[ci];
                    } while (ca[ci] != ci); ca[i] = ci;
                }
                foreach (var j in dict.ValuesWithKey(hc))
                {
                    int cj = ca[j]; if (ca[cj] != cj)
                    {
                        do
                        {
                            cj = ca[cj];
                        } while (ca[cj] != cj); ca[j] = cj;
                    }
                    if (ci == cj || p != pa[j])
                    {
                        continue;
                    }
                    bit >>= 1; if (bit == 0)
                    {
                        rndBits = rnd.UniformInt(); bit = 1 << 30;
                    }
                    if ((rndBits & bit) != 0)
                    {
                        ca[ci] = cj; ca[i] = cj; ci = cj;
                    }
                    else
                    {
                        ca[cj] = ci; ca[j] = ci;
                    }
                }
                dict[hc] = i;
            }
            Init();
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Returns a uniformly distributed double in the open interval
        /// (0.0, 1.0). Note, that two random values are used to make all 53
        /// bits random.
        /// </summary>
        public static double UniformDoubleFullOpen(this IRandomUniform rnd)
        {
            if (rnd.GeneratesFullDoubles)
            {
                return(rnd.UniformDoubleOpen());
            }
            long r;

            do
            {
                r = ((~0xfL & (long)rnd.UniformInt()) << 22)
                    | ((long)rnd.UniformInt() >> 5);
            }while (r == 0);
            return(r * (1.0 / 9007199254740992.0));
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Creates an unordered array of subsetCount int indices that
        /// constitute a subset of all ints in the range [0, count-1].
        /// O(subsetCount) for subsetCount &lt;&lt; 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 int[] CreateSmallRandomSubsetIndexArray(
            this IRandomUniform rnd, int subsetCount, int count)
        {
            Requires.That(subsetCount >= 0 && subsetCount <= count);
            var subsetIndices = new IntSet(subsetCount);

            for (int i = 0; i < subsetCount; i++)
            {
                int index;
                do
                {
                    index = rnd.UniformInt(count);
                }while (!subsetIndices.TryAdd(index));
            }
            return(subsetIndices.ToArray());
        }
Ejemplo n.º 30
0
        /// <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 &lt;&lt; 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());
        }