Ejemplo n.º 1
0
        /// <summary>
        /// Returns a gaussian distributed double.
        /// </summary>
        public double GetDouble()
        {
            double value;

            if (!Double.IsNaN(m_cachedValue))
            {
                value         = m_cachedValue;
                m_cachedValue = Double.NaN;
            }
            else
            {
                // using the polar form of the Box-Muller transformation to
                // transform two random uniform values to two gaussian
                // distributed values
                double x1, x2, w;
                do
                {
                    x1 = 2.0 * m_rndUniform.UniformDouble() - 1.0;
                    x2 = 2.0 * m_rndUniform.UniformDouble() - 1.0;
                    w  = x1 * x1 + x2 * x2;
                } while (w >= 1.0);

                w             = System.Math.Sqrt((-2.0 * System.Math.Log(w)) / w);
                value         = x1 * w;
                m_cachedValue = x2 * w;
            }

            return(value);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns a 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 UniformV3dDirection(this IRandomUniform rnd)
        {
            double phi = rnd.UniformDouble() * Constant.PiTimesTwo;
            double z   = 1.0 - rnd.UniformDouble() * 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.º 3
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.º 4
0
 public HaltonRandomSeries(
     int haltonCount, IRandomUniform randomUniform)
 {
     m_haltonStateArray = new double[haltonCount].SetByIndex(
         i => randomUniform.UniformDouble());
     m_randomUniform = randomUniform;
 }
Ejemplo n.º 5
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.º 6
0
        public double UniformDouble(int seriesIndex)
        {
            var ind = m_index[seriesIndex]++;
            var rnd = m_series[ind++ % m_series.Length][seriesIndex];

            rnd += m_seed[seriesIndex];                                                 // shift complete pattern by seed
            return(((rnd + (m_jitter ? m_rnd.UniformDouble() : 0.0)) * m_norm).Frac()); // optionally add sub-pixel jittering
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Fills the specified array with random doubles in the half-open
        /// interval [0.0, 1.0).
        /// </summary>
        public static void FillUniform(
            this IRandomUniform rnd, double[] array)
        {
            long count = array.LongLength;

            for (long i = 0; i < count; i++)
            {
                array[i] = rnd.UniformDouble();
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Returns a uniformly distributed double in the half-open interval
        /// [0.0, 1.0). Note, that two random values are used to make all 53
        /// bits random. If you use this repeatedly, consider using a 64-bit
        /// random generator, which can  provide such doubles directly using
        /// UniformDouble().
        /// </summary>
        public static double UniformDoubleFull(this IRandomUniform rnd)
        {
            if (rnd.GeneratesFullDoubles)
            {
                return(rnd.UniformDouble());
            }
            long r = ((~0xfL & (long)rnd.UniformInt()) << 22)
                     | ((long)rnd.UniformInt() >> 5);

            return(r * (1.0 / 9007199254740992.0));
        }
Ejemplo n.º 9
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.º 10
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.º 11
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 signficantly
        /// 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)
        {
            long count = array.LongLength;

            Requires.That(subsetCount >= 0 && subsetCount <= count);
            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.º 12
0
        /// <summary>
        /// Fills the specified array with fully random doubles (53 random
        /// bits) in the half-open interval [0.0, 1.0).
        /// </summary>
        public static void FillUniformFull(
            this IRandomUniform rnd, double[] array)
        {
            long count = array.LongLength;

            if (rnd.GeneratesFullDoubles)
            {
                for (long i = 0; i < count; i++)
                {
                    array[i] = rnd.UniformDoubleFull();
                }
            }
            else
            {
                for (long i = 0; i < count; i++)
                {
                    array[i] = rnd.UniformDouble();
                }
            }
        }
 /// <summary>
 /// Retrieve random index distributed proportional to probability density function.
 /// Uses binary search O(log n).
 /// </summary>
 public int Sample(IRandomUniform rnd)
 {
     return(Sample(rnd.UniformDouble()));
 }
Ejemplo n.º 14
0
 public double UniformDouble(int seriesIndex)
 {
     return(m_rnd.UniformDouble());
 }
 public static int SampleCDF(double[] cdf, IRandomUniform rnd)
 {
     return(SampleCDF(cdf, rnd.UniformDouble()));
 }
Ejemplo n.º 16
0
 public static V3d UniformV3d(this IRandomUniform rnd, Box3d box)
 {
     return(box.Lerp(rnd.UniformDouble(),
                     rnd.UniformDouble(),
                     rnd.UniformDouble()));
 }
Ejemplo n.º 17
0
 public static V3d UniformV3d(this IRandomUniform rnd)
 {
     return(new V3d(rnd.UniformDouble(),
                    rnd.UniformDouble(),
                    rnd.UniformDouble()));
 }
Ejemplo n.º 18
0
 public static V2d UniformV2d(this IRandomUniform rnd, Box2d box)
 {
     return(new V2d(box.Min.X + rnd.UniformDouble() * (box.Max.X - box.Min.X),
                    box.Min.Y + rnd.UniformDouble() * (box.Max.Y - box.Min.Y)));
 }