/// <summary> /// Construct a uniform distribution generator with the provided random source. /// If {signed} is false the distribution interval is [0, scale), otherwise it is (-scale, +scale). /// </summary> public UniformDistribution(double scale, bool signed, IRandomSource rng) { _rng = rng; _scale = scale; _signed = signed; // Note. We predetermine which of these four function variants to use at construction time, // thus avoiding the two condition tests on each invocation of Sample(). // I.e. this is a micro-optimization. if (signed) { if (1.0 == scale) { _sampleFn = () => { return((_rng.NextDouble() - 0.5) * 2.0); }; } else { _sampleFn = () => { return((_rng.NextDouble() - 0.5) * 2.0 * scale); }; } } else { if (1.0 == scale) { _sampleFn = () => { return(_rng.NextDouble()); }; } else { _sampleFn = () => { return(_rng.NextDouble() * scale); }; } } }
/// <summary> /// Get the next sample from the gaussian distribution. /// </summary> public double NextDouble() { if (null != _spareValue) { double tmp = _spareValue.Value; _spareValue = null; return(tmp); } // Generate two new gaussian values. double x, y, sqr; // We need a non-zero random point inside the unit circle. do { x = 2.0 * _rng.NextDouble() - 1.0; y = 2.0 * _rng.NextDouble() - 1.0; sqr = x * x + y * y; }while(sqr > 1.0 || sqr == 0); // Make the Box-Muller transformation. double fac = Math.Sqrt(-2.0 * Math.Log(sqr) / sqr); _spareValue = x * fac; return(y * fac); }
/// <summary> /// For activation functions that accept auxiliary arguments; generates random initial values for aux arguments for newly /// added nodes (from an 'add neuron' mutation). /// </summary> public double[] GetRandomAuxArgs(IRandomSource rng, double connectionWeightRange) { double[] auxArgs = new double[2]; auxArgs[0] = (rng.NextDouble() - 0.5) * 2.0; auxArgs[1] = rng.NextDouble(); return(auxArgs); }
private void AddBranchesToSegment(TreeSegment segment, double absoluteAngle) { if (segment.Depth == MaxDepth) { return; } if (segment.Thickness < 0.002) { return; } const double maxDevAngle = 0.1 * TAU; const double gravityNormal = 0.75 * TAU; var deltaAngle = Math.Atan2(Math.Sin(gravityNormal - absoluteAngle), Math.Cos(gravityNormal - absoluteAngle)); if (Math.Abs(deltaAngle) < maxDevAngle) { return; } var randomDeviationAngle = random.NextDouble() * 2 * MaxRotationFactor - MaxRotationFactor; var deviationAngle = BiasedValue(0, randomDeviationAngle, 1); var branchingSpread = random.UniformRandom(BranchSpreadMin, BranchSpreadMax); if (segment.Depth == 0) { AddAngledBranch(segment, deviationAngle - branchingSpread / 2, absoluteAngle); AddAngledBranch(segment, deviationAngle + branchingSpread / 2, absoluteAngle); AddAngledBranch(segment, deviationAngle, absoluteAngle); } else if (random.NextDouble() <= ProbabilitySingleBranch) { // no branching AddAngledBranch(segment, deviationAngle, absoluteAngle); } else { // branching var leftAngle = deviationAngle - branchingSpread / 2; var rightAngle = deviationAngle + branchingSpread / 2; if (random.NextDouble() < 0.8) { var rndAngle = random.UniformRandom(deviationAngle - branchingSpread, deviationAngle + branchingSpread); var thickness = random.UniformRandom(0.25, 0.5); AddAngledBranch(segment, rndAngle, absoluteAngle, extraThicknessFactor: thickness); } AddAngledBranch(segment, leftAngle, absoluteAngle); AddAngledBranch(segment, rightAngle, absoluteAngle); } }
/// <summary> /// Initialise agent and prey positions. The prey is positioned randomly with at least 4 empty squares between it and a wall (in all directions). /// The agent is positioned randomly but such that the prey is within sensor range (distance 2 or less). /// </summary> public void InitPositions() { // Random pos at least 4 units away from any wall. _preyPos._x = 4 + _rng.Next(_gridSize - 8); _preyPos._y = 4 + _rng.Next(_gridSize - 8); // Agent position. Within range of the prey. double t = 2.0 * Math.PI * _rng.NextDouble(); // Random angle. double r = 2.0 + _rng.NextDouble() * 2.0; // Distance between 2 and 4. _agentPos._x = _preyPos._x + (int)Math.Floor(Math.Cos(t) * r); _agentPos._y = _preyPos._y + (int)Math.Floor(Math.Sin(t) * r); }
/// <summary> /// Initialise agent and prey positions. The prey is positioned randomly with at least 4 empty squares between it and a wall (in all directions). /// The agent is positioned randomly but such that the prey is within sensor range (distance 2 or less). /// </summary> public void InitPositions() { // Random position at least 4 units away from any wall. _preyPos._x = 4 + _rng.Next(_gridSize - 8); _preyPos._y = 4 + _rng.Next(_gridSize - 8); // Agent position. The angle from the prey is chosen at random, and the distance from the prey is randomly chosen between 2 and 4. double t = 2.0 * Math.PI * _rng.NextDouble(); // Random angle. double r = 2.0 + _rng.NextDouble() * 2.0; // Distance between 2 and 4. _agentPos._x = _preyPos._x + (int)Math.Truncate(Math.Cos(t) * r); _agentPos._y = _preyPos._y + (int)Math.Truncate(Math.Sin(t) * r); }
// Преобразование Бокса-Мюллера public static double BoxMullerDouble(this IRandomSource r) { double x, y, s; do { x = 2.0 * r.NextDouble() - 1.0; y = 2.0 * r.NextDouble() - 1.0; s = x * x + y * y; }while (s >= 1.0); double fac = Math.Sqrt(-2.0 * Math.Log(s) / s); return(x * fac); }
/// <summary> /// Fill a span with samples from a binary/Bernoulli distribution with the given probaility of sampling 'true'. /// </summary> /// <param name="rng">Random source.</param> /// <param name="probability">Probability of sampling 'true'.</param> /// <param name="span">The span to fill with samples.</param> public static void SampleBernoulli(IRandomSource rng, double probability, Span <bool> span) { for (int i = 0; i < span.Length; i++) { span[i] = rng.NextDouble() < probability; } }
/// <summary> /// Sample from the provided discrete probability distribution. /// </summary> public int Sample(IRandomSource rng) { // Throw the ball and return an integer indicating the outcome. double sample = rng.NextDouble(); double acc = 0.0; for (int i = 0; i < _probArr.Length; i++) { acc += _probArr[i]; if (sample < acc) { return(_labelArr[i]); } } // We might get here through floating point arithmetic rounding issues. // e.g. accumulator == throwValue. // Find a nearby non-zero probability to select. // Wrap around to start of array. for (int i = 0; i < _probArr.Length; i++) { if (0.0 != _probArr[i]) { return(_labelArr[i]); } } // If we get here then we have an array of zero probabilities. throw new InvalidOperationException("Invalid operation. No non-zero probabilities to select."); }
public void BuildHistogramData() { IRandomSource rng = RandomDefaults.CreateRandomSource(0); int iters = 10_000; double[] vals = new double[iters]; for (int i = 0; i < iters; i++) { vals[i] = 1000.0 + (rng.NextDouble() * 2.0) - 1.0; } // Construct a histogram on the array of values. HistogramData hist = NumericsUtils.BuildHistogramData(vals, 8); // We expect samples to be approximately evenly distributed over the histogram buckets. for (int i = 0; i < hist.FrequencyArray.Length; i++) { Assert.True(hist.FrequencyArray[i] > (iters / 8) * 0.8); } // We expect min and max to be close to 999 and 1001 respectively. Assert.True(hist.Max <= (1001) && hist.Max > (1001) - 0.1); Assert.True(hist.Min >= (999) && hist.Min < (999) + 0.1); }
public static double UniformRandom(this IRandomSource randomSource, double lowerLimit, double upperLimit) { var delta = (upperLimit - lowerLimit); var randAmount = randomSource.NextDouble() * delta; return(lowerLimit + randAmount); }
/// <summary> /// Rounds up or down to a whole number by using the fractional part of the input value /// as the probability that the value will be rounded up. /// /// This is useful if we wish to round values and then sum them without generating a rounding bias. /// For monetary rounding this problem is solved with rounding to e.g. the nearest even number which /// then causes a bias towards even numbers. /// /// This solution is more appropriate for certain types of scientific values. /// </summary> public static double ProbabilisticRound(double val, IRandomSource rng) { double integerPart = Math.Floor(val); double fractionalPart = val - integerPart; return(rng.NextDouble() < fractionalPart ? integerPart + 1.0 : integerPart); }
/// <summary> /// Fill a span with samples from the uniform distribution with interval [0, 1). /// </summary> /// <param name="rng">Random source.</param> /// <param name="span">The span to fill with samples.</param> public static void Sample(IRandomSource rng, Span <double> span) { for (int i = 0; i < span.Length; i++) { span[i] = rng.NextDouble(); } }
/// <summary> /// Fill an array with samples from a binary/Bernoulli distribution with the specified boolean true probability. /// </summary> /// <param name="rng">Random source.</param> /// <param name="probability">Probability of sampling boolean true.</param> /// <param name="buf">The array to fill with samples.</param> public static void SampleBernoulli(IRandomSource rng, double probability, bool[] buf) { for (int i = 0; i < buf.Length; i++) { buf[i] = (rng.NextDouble() < probability); } }
/// <summary> /// Fill an array with samples from the uniform distribution with interval [0, 1). /// </summary> /// <param name="rng">Random source.</param> /// <param name="buf">The array to fill with samples.</param> public static void Sample(IRandomSource rng, double[] buf) { for (int i = 0; i < buf.Length; i++) { buf[i] = rng.NextDouble(); } }
public DateTime Measure() { var perc = _randomSource.NextDouble(); var diff = _maxDate.Ticks - _minDate.Ticks; var result = new DateTime((long)(_minDate.Ticks + (perc * diff))); return(result); }
public double Measure() { double u; double s; do { u = 2.0 * _source.NextDouble() - 1.0; var v = 2.0 * _source.NextDouble() - 1.0; s = u * u + v * v; }while (s >= 1.0); double fac = Math.Sqrt(-2.0 * Math.Log(s) / s); var result = u * fac; return(_sigma * result + _mean); }
/// <summary> /// Rounds up or down to a whole number by using the fractional part of the input value /// as the probability that the value will be rounded up. /// </summary> /// <remarks> /// This is useful if we wish to round values and then sum them without generating a rounding bias. /// For monetary rounding this problem is solved with rounding to e.g. the nearest even number, /// which then causes a bias towards even numbers. As such, this solution is more appropriate for /// certain types of scientific calculations. /// </remarks> /// <param name="val">The value to round.</param> /// <param name="rng">Random source.</param> /// <returns>The rounded value.</returns> public static double StochasticRound(double val, IRandomSource rng) { // TODO: Performance tune? double integerPart = Math.Floor(val); double fractionalPart = val - integerPart; return(rng.NextDouble() < fractionalPart ? integerPart + 1.0 : integerPart); }
/// <summary> /// Fill a span with samples from the uniform distribution with interval [0, max). /// </summary> /// <param name="rng">Random source.</param> /// <param name="max">Maximum value (exclusive).</param> /// <param name="span">The span to fill with samples.</param> public static void Sample(IRandomSource rng, double max, Span <double> span) { Debug.Assert(max >= 0.0); for (int i = 0; i < span.Length; i++) { span[i] = rng.NextDouble() * max; } }
/// <summary> /// Fill an array with samples from the uniform distribution with interval [0, max). /// </summary> /// <param name="rng">Random source.</param> /// <param name="max">Maximum value (exclusive).</param> /// <param name="buf">The array to fill with samples.</param> public static void Sample(IRandomSource rng, double max, double[] buf) { Debug.Assert(max >= 0.0); for (int i = 0; i < buf.Length; i++) { buf[i] = rng.NextDouble() * max; } }
/// <summary> /// Take a sample from the standard Gaussian distribution, i.e. with mean of 0 and standard deviation of 1. /// </summary> /// <param name="rng">Random source.</param> /// <returns>A pair of random samples (because the Box-Muller transform generates samples in pairs).</returns> public static (double, double) Sample(IRandomSource rng) { // Generate two new Gaussian values. double x, y, sqr; // We need a non-zero random point inside the unit circle. do { x = 2.0 * rng.NextDouble() - 1.0; y = 2.0 * rng.NextDouble() - 1.0; sqr = (x * x) + (y * y); }while(sqr > 1.0 || sqr == 0); // Make the Box-Muller transformation. double fac = Math.Sqrt((-2.0 * Math.Log(sqr)) / sqr); // Return two samples. return(x * fac, y *fac); }
/// <summary> /// Take a sample from the uniform distribution with interval (-1, 1). /// </summary> /// <param name="rng">Random source.</param> /// <returns>A random sample.</returns> public static double SampleSigned(IRandomSource rng) { double sample = rng.NextDouble(); if (rng.NextBool()) { sample *= -1.0f; } return(sample); }
/// <summary> /// Returns a random value sampled from the standard Gaussian distribution, i.e., with mean of 0 and standard deviation of 1. /// </summary> /// <param name="rng">Random source.</param> /// <returns>A new random sample.</returns> public static double Sample(IRandomSource rng) { for (;;) { // Generate 64 random bits. ulong u = rng.NextULong(); // Note. 61 random bits are required and therefore the lowest three bits are discarded // (a typical characteristic of PRNGs is that the least significant bits exhibit lower // quality randomness than the higher bits). // Select a segment (7 bits, bits 3 to 9). int s = (int)((u >> 3) & 0x7f); // Select the sign bit (bit 10), and convert to a double-precision float value of -1.0 or +1.0 accordingly. // Notes. // Here we convert the single chosen bit directly into IEEE754 double-precision floating-point format. // Previously this conversion used a branch, which is considerably slower because modern superscalar // CPUs rely heavily on branch prediction, but the outcome of this branch is pure random noise and thus // entirely unpredictable, i.e. the absolute worse case scenario! double sign = BitConverter.Int64BitsToDouble(unchecked ((long)(((u & 0x400UL) << 53) | __oneBits))); // Get a uniform random value with interval [0, 2^53-1], or in hexadecimal [0, 0x1f_ffff_ffff_ffff] // (i.e. a random 53 bit number) (bits 11 to 63). ulong u2 = u >> 11; // Special case for the base segment. if (s == 0) { if (u2 < __xComp[0]) { // Generated x is within R0. return(u2 * __INCR * __A_Div_Y0 * sign); } // Generated x is in the tail of the distribution. return(SampleTail(rng) * sign); } // All other segments. if (u2 < __xComp[s]) { // Generated x is within the rectangle. return(u2 * __INCR * __x[s] * sign); } // Generated x is outside of the rectangle. // Generate a random y coordinate and test if our (x,y) is within the distribution curve. // This execution path is relatively slow/expensive (makes a call to Math.Exp()) but is relatively rarely executed, // although more often than the 'tail' path (above). double x = u2 * __INCR * __x[s]; if (__y[s - 1] + ((__y[s] - __y[s - 1]) * rng.NextDouble()) < GaussianPdfDenorm(x)) { return(x * sign); } } }
public void TestProbabilisticRound() { IRandomSource rng = RandomDefaults.CreateRandomSource(0); for (int i = 0; i < 1000000; i++) { double valReal = 100 * rng.NextDouble(); double valRound = NumericsUtils.ProbabilisticRound(valReal, rng); Assert.IsTrue(valRound == Math.Floor(valReal) || valRound == Math.Ceiling(valReal)); } }
/// <summary> /// Fill a span with samples from the uniform distribution with interval [min, max). /// </summary> /// <param name="rng">Random source.</param> /// <param name="min">Minimum value (inclusive).</param> /// <param name="max">Maximum value (exclusive).</param> /// <param name="span">The span to fill with samples.</param> public static void Sample(IRandomSource rng, double min, double max, Span <double> span) { Debug.Assert(max >= min); double delta = max - min; for (int i = 0; i < span.Length; i++) { span[i] = min + (rng.NextDouble() * delta); } }
/// <summary> /// Fill an array with samples from the uniform distribution with interval [min, max). /// </summary> /// <param name="rng">Random source.</param> /// <param name="min">Minimum value (inclusive).</param> /// <param name="max">Maximum value (exclusive).</param> /// <param name="buf">The array to fill with samples.</param> public static void Sample(IRandomSource rng, double min, double max, double[] buf) { Debug.Assert(max >= min); double delta = max - min; for (int i = 0; i < buf.Length; i++) { buf[i] = min + (rng.NextDouble() * delta); } }
/// <summary> /// Take a sample from the uniform distribution with interval (-max, max). /// </summary> /// <param name="rng">Random source.</param> /// <param name="max">Maximum absolute value (exclusive).</param> /// <returns>A random sample.</returns> public static double SampleSigned(IRandomSource rng, double max) { Debug.Assert(max >= 0.0); double sample = rng.NextDouble() * max; if (rng.NextBool()) { sample *= -1.0; } return(sample); }
/// <summary> /// Take a sample from the standard gaussian distribution, i.e. with mean of 0 and standard deviation of 1. /// </summary> public double SampleStandard() { for (;;) { // Generate 64 random bits. ulong u = _rng.NextULong(); // Notes. We require 61 of the random bits in total so we discard the lowest three bits because these // generally exhibit lower quality randomness than the higher bits (depending on the PRNG is use, but // it is a common feature of many PRNGs). // Select a segment (7 bits, bits 3 to 9). int s = (int)((u >> 3) & 0x7f); // Select sign bit (bit 10). double sign = ((u & 0x400) == 0) ? 1.0 : -1.0; // Get a uniform random value with interval [0, 2^53-1], or in hexadecimal [0, 0x1f_ffff_ffff_ffff] // (i.e. a random 53 bit number) (bits 11 to 63). ulong u2 = u >> 11; // Special case for the base segment. if (0 == s) { if (u2 < _xComp[0]) { // Generated x is within R0. return(u2 * __INCR * _A_Div_Y0 * sign); } // Generated x is in the tail of the distribution. return(SampleTail() * sign); } // All other segments. if (u2 < _xComp[s]) { // Generated x is within the rectangle. return(u2 * __INCR * _x[s] * sign); } // Generated x is outside of the rectangle. // Generate a random y coordinate and test if our (x,y) is within the distribution curve. // This execution path is relatively slow/expensive (makes a call to Math.Exp()) but is relatively rarely executed, // although more often than the 'tail' path (above). double x = u2 * __INCR * _x[s]; if (_y[s - 1] + ((_y[s] - _y[s - 1]) * _rng.NextDouble()) < GaussianPdfDenorm(x)) { return(x * sign); } } }
/// <summary> /// Take a sample from the standard Gaussian distribution, i.e. with mean of 0 and standard deviation of 1. /// </summary> /// <returns>A random sample.</returns> public static double Sample(this IRandomSource rng) { for (; ;) { // Generate 64 random bits. ulong u = rng.NextULong(); // Note. 61 random bits are required and therefore the lowest three bits are discarded // (a typical characteristic of PRNGs is that the least significant bits exhibit lower // quality randomness than the higher bits). // Select a segment (7 bits, bits 3 to 9). int s = (int)((u >> 3) & 0x7f); // Select sign bit (bit 10). double sign = ((u & 0x400) == 0) ? 1.0 : -1.0; // Get a uniform random value with interval [0, 2^53-1], or in hexadecimal [0, 0x1f_ffff_ffff_ffff] // (i.e. a random 53 bit number) (bits 11 to 63). ulong u2 = u >> 11; // Special case for the base segment. if (0 == s) { if (u2 < __xComp[0]) { // Generated x is within R0. return(u2 * __INCR * __A_Div_Y0 * sign); } // Generated x is in the tail of the distribution. return(SampleTail(rng) * sign); } // All other segments. if (u2 < __xComp[s]) { // Generated x is within the rectangle. return(u2 * __INCR * __x[s] * sign); } // Generated x is outside of the rectangle. // Generate a random y coordinate and test if our (x,y) is within the distribution curve. // This execution path is relatively slow/expensive (makes a call to Math.Exp()) but is relatively rarely executed, // although more often than the 'tail' path (above). double x = u2 * __INCR * __x[s]; if (__y[s - 1] + ((__y[s] - __y[s - 1]) * rng.NextDouble()) < GaussianPdfDenorm(x)) { return(x * sign); } } }
/// <summary> /// Fill an array with samples from the uniform distribution with interval (-max, max). /// </summary> /// <param name="rng">Random source.</param> /// <param name="max">Maximum absolute value (exclusive).</param> /// <param name="buf">The array to fill with samples.</param> public static void SampleSigned(IRandomSource rng, double max, double[] buf) { Debug.Assert(max >= 0.0); for (int i = 0; i < buf.Length; i++) { double sample = rng.NextDouble() * max; if (rng.NextBool()) { sample *= -1.0; } buf[i] = sample; } }