/// <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); }
/// <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)); }
/// <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); }
public HaltonRandomSeries( int haltonCount, IRandomUniform randomUniform) { m_haltonStateArray = new double[haltonCount].SetByIndex( i => randomUniform.UniformDouble()); m_randomUniform = randomUniform; }
public static V2d UniformV2dDirection(this IRandomUniform rnd) { double phi = rnd.UniformDouble() * Constant.PiTimesTwo; return(new V2d(System.Math.Cos(phi), System.Math.Sin(phi))); }
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 }
/// <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(); } }
/// <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)); }
/// <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)); } }
/// <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)); } }
/// <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); }
/// <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())); }
public double UniformDouble(int seriesIndex) { return(m_rnd.UniformDouble()); }
public static int SampleCDF(double[] cdf, IRandomUniform rnd) { return(SampleCDF(cdf, rnd.UniformDouble())); }
public static V3d UniformV3d(this IRandomUniform rnd, Box3d box) { return(box.Lerp(rnd.UniformDouble(), rnd.UniformDouble(), rnd.UniformDouble())); }
public static V3d UniformV3d(this IRandomUniform rnd) { return(new V3d(rnd.UniformDouble(), rnd.UniformDouble(), rnd.UniformDouble())); }
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))); }