Esempio n. 1
0
        /// <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); };
                }
            }
        }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 3
0
 /// <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);
 }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        /// <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);
        }
Esempio n. 6
0
        /// <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);
        }
Esempio n. 8
0
 /// <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;
     }
 }
Esempio n. 9
0
        /// <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.");
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        public static double UniformRandom(this IRandomSource randomSource, double lowerLimit, double upperLimit)
        {
            var delta      = (upperLimit - lowerLimit);
            var randAmount = randomSource.NextDouble() * delta;

            return(lowerLimit + randAmount);
        }
Esempio n. 12
0
        /// <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);
        }
Esempio n. 13
0
 /// <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();
     }
 }
Esempio n. 14
0
 /// <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);
     }
 }
Esempio n. 15
0
 /// <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();
     }
 }
Esempio n. 16
0
        public DateTime Measure()
        {
            var perc   = _randomSource.NextDouble();
            var diff   = _maxDate.Ticks - _minDate.Ticks;
            var result = new DateTime((long)(_minDate.Ticks + (perc * diff)));

            return(result);
        }
Esempio n. 17
0
        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);
        }
Esempio n. 18
0
        /// <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);
        }
Esempio n. 19
0
        /// <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;
            }
        }
Esempio n. 20
0
        /// <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;
            }
        }
Esempio n. 21
0
        /// <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);
        }
Esempio n. 22
0
        /// <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);
        }
Esempio n. 23
0
        /// <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);
                }
            }
        }
Esempio n. 24
0
        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));
            }
        }
Esempio n. 25
0
        /// <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);
            }
        }
Esempio n. 26
0
        /// <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);
            }
        }
Esempio n. 27
0
        /// <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);
                }
            }
        }
Esempio n. 30
0
        /// <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;
            }
        }