Ejemplo n.º 1
0
        /// <summary>
        /// Construct with the provided RNG source.
        /// </summary>
        public UniformDistribution(IRandomSource rng, float scale, bool signed)
        {
            _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.NextFloat() - 0.5f) * 2.0f); };
                }
                else
                {
                    _sampleFn = () => { return((_rng.NextFloat() - 0.5f) * 2.0f * scale); };
                }
            }
            else
            {
                if (1.0 == scale)
                {
                    _sampleFn = () => { return(_rng.NextFloat()); };
                }
                else
                {
                    _sampleFn = () => { return(_rng.NextFloat() * scale); };
                }
            }
        }
Ejemplo n.º 2
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.
            float t = 2f * MathF.PI * _rng.NextFloat();                 // Random angle.
            float r = MathF.FusedMultiplyAdd(2f, _rng.NextFloat(), 2f); // A distance between 2 and 4.

            _agentPos.X = _preyPos.X + (int)MathF.Truncate(MathF.Cos(t) * r);
            _agentPos.Y = _preyPos.Y + (int)MathF.Truncate(MathF.Sin(t) * r);
        }
Ejemplo n.º 3
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, float probability, Span <bool> span)
 {
     for (int i = 0; i < span.Length; i++)
     {
         span[i] = rng.NextFloat() < probability;
     }
 }
Ejemplo n.º 4
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, float probability, bool[] buf)
 {
     for (int i = 0; i < buf.Length; i++)
     {
         buf[i] = (rng.NextFloat() < probability);
     }
 }
Ejemplo n.º 5
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 <float> span)
 {
     for (int i = 0; i < span.Length; i++)
     {
         span[i] = rng.NextFloat();
     }
 }
Ejemplo n.º 6
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, float[] buf)
 {
     for (int i = 0; i < buf.Length; i++)
     {
         buf[i] = rng.NextFloat();
     }
 }
Ejemplo n.º 7
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, float max, float[] buf)
        {
            Debug.Assert(max >= 0.0);

            for (int i = 0; i < buf.Length; i++)
            {
                buf[i] = rng.NextFloat() * max;
            }
        }
Ejemplo n.º 8
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, float max, Span <float> span)
        {
            Debug.Assert(max >= 0.0);

            for (int i = 0; i < span.Length; i++)
            {
                span[i] = rng.NextFloat() * max;
            }
        }
Ejemplo n.º 9
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 float SampleSigned(IRandomSource rng)
        {
            float sample = rng.NextFloat();

            if (rng.NextBool())
            {
                sample *= -1.0f;
            }
            return(sample);
        }
Ejemplo n.º 10
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 (float, float) Sample(IRandomSource rng)
        {
            // Generate two new Gaussian values.
            float x, y, sqr;

            // We need a non-zero random point inside the unit circle.
            do
            {
                x   = (2f * rng.NextFloat()) - 1f;
                y   = (2f * rng.NextFloat()) - 1f;
                sqr = (x * x) + (y * y);
            }while(sqr > 1f || sqr == 0f);

            // Make the Box-Muller transformation.
            float fac = MathF.Sqrt((-2f * MathF.Log(sqr)) / sqr);

            // Return two samples.
            return(x * fac, y *fac);
        }
Ejemplo n.º 11
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 float Sample(IRandomSource rng)
        {
            for (;;)
            {
                // Generate 64 random bits.
                ulong u = rng.NextULong();

                // Note. 32 random bits are required and therefore the lowest 32 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 32 to 38).
                int s = (int)((u >> 32) & 0x7f);

                // Select the sign bit (bit 39), and convert to a single-precision float value of -1.0 or +1.0 accordingly.
                // Notes.
                // Here we convert the single chosen bit directly into IEEE754 single-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!
                float sign = BitConverter.Int32BitsToSingle(unchecked ((int)(((u & 0x80_0000_0000UL) >> 8) | __oneBits)));

                // Get a uniform random value with interval [0, 2^24-1], or in hexadecimal [0, 0xff_ffff]
                // (i.e. a random 24 bit number) (bits 40 to 63).
                ulong u2 = u >> 40;

                // 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).
                float x = u2 * __INCR * __x[s];
                if (__y[s - 1] + ((__y[s] - __y[s - 1]) * rng.NextFloat()) < GaussianPdfDenormF(x))
                {
                    return(x * sign);
                }
            }
        }
Ejemplo n.º 12
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, float min, float max, Span <float> span)
        {
            Debug.Assert(max >= min);

            float delta = max - min;

            for (int i = 0; i < span.Length; i++)
            {
                span[i] = min + (rng.NextFloat() * delta);
            }
        }
Ejemplo n.º 13
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, float min, float max, float[] buf)
        {
            Debug.Assert(max >= min);

            float delta = max - min;

            for (int i = 0; i < buf.Length; i++)
            {
                buf[i] = min + (rng.NextFloat() * delta);
            }
        }
Ejemplo n.º 14
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 float SampleSigned(IRandomSource rng, float max)
        {
            Debug.Assert(max >= 0.0);

            float sample = rng.NextFloat() * max;

            if (rng.NextBool())
            {
                sample *= -1.0f;
            }
            return(sample);
        }
Ejemplo n.º 15
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, float max, float[] buf)
        {
            Debug.Assert(max >= 0.0);

            for (int i = 0; i < buf.Length; i++)
            {
                float sample = rng.NextFloat() * max;
                if (rng.NextBool())
                {
                    sample *= -1.0f;
                }
                buf[i] = sample;
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Sample from the provided discrete probability distribution.
        /// </summary>
        /// <param name="rng">Random source.</param>
        /// <param name="dist">The discrete distribution to sample from.</param>
        /// <returns>A sample from the discrete distribution.</returns>
        public static int Sample(IRandomSource rng, DiscreteDistribution dist)
        {
            float[] pArr = dist.Probabilities;

            // Obtain a random threshold value by sampling uniformly from interval [0,1).
            float thresh = rng.NextFloat();

            // ENHANCEMENT: Precalc running sum over pArr, and use binary search over pArr if its length is > 10 (or thereabouts).
            // Loop through the discrete probabilities, accumulating as we go and stopping once
            // the accumulator is greater than the random sample.
            float acc = 0f;

            for (int i = 0; i < pArr.Length; i++)
            {
                acc += pArr[i];
                if (acc > thresh)
                {
                    return(dist.Labels[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 < pArr.Length; i++)
            {
                if (pArr[i] != 0.0)
                {
                    return(dist.Labels[i]);
                }
            }

            // If we get here then we have an array of zero probabilities.
            throw new InvalidOperationException("Invalid operation. No non-zero probabilities to select.");
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Take a sample from the uniform distribution with interval [0, max).
 /// </summary>
 /// <param name="rng">Random source.</param>
 /// <param name="max">Maximum value (exclusive).</param>
 /// <returns>A random sample.</returns>
 public static float Sample(IRandomSource rng, float max)
 {
     Debug.Assert(max >= 0.0);
     return(rng.NextFloat() * max);
 }
Ejemplo n.º 18
0
        /// <summary>
        /// Add objects to the Box2d world.
        /// </summary>
        protected override void PopulateWorld()
        {
            // ==== Define the ground body ====
            BodyDef groundBodyDef = new BodyDef();

            groundBodyDef.Position.Set(_trackLengthHalf, -1f);

            // Call the body factory which creates the ground box shape.
            // The body is also added to the world.
            Body groundBody = _world.CreateBody(groundBodyDef);

            // Define the ground box shape.
            PolygonDef groundShapeDef = new PolygonDef();

            // The extents are the half-widths of the box.
            groundShapeDef.SetAsBox(_trackLengthHalf + 1f, 1f);
            groundShapeDef.Friction            = _simParams._defaultFriction;
            groundShapeDef.Restitution         = _simParams._defaultRestitution;
            groundShapeDef.Filter.CategoryBits = 0x3;

            // Add the ground shape to the ground body.
            groundBody.CreateShape(groundShapeDef);

            // Add some small mounds/bumps to the ground.
            for (float x = -1f; x < 40f; x += 0.4f + ((_rng.NextFloat() - 0.5f) * 0.15f))
            {
                WalkerWorldUtils.CreateMound(_world, x, 0f, _simParams._defaultFriction, _simParams._defaultRestitution);
            }

            // ==== Define walker torso.
            float walkerX = 0f;
            float walkerY = 1.30f;// + ((float)_rng.NextDouble() * 0.1f);

            BodyDef torsoBodyDef = new BodyDef();

            torsoBodyDef.Position.Set(walkerX, walkerY);
            torsoBodyDef.IsBullet = true;

            // Create walker torso.
            _torsoBody = _world.CreateBody(torsoBodyDef);
            PolygonDef torsoShapeDef = new PolygonDef();

            torsoShapeDef.SetAsBox(0.10f, 0.30f);
            torsoShapeDef.Friction            = _simParams._defaultFriction;
            torsoShapeDef.Restitution         = 0f;
            torsoShapeDef.Density             = 2f;
            torsoShapeDef.Filter.CategoryBits = 0x2;
            _torsoBody.CreateShape(torsoShapeDef);
            _torsoBody.SetMassFromShapes();

            // ===== Create legs.
            // Leg joint definition.
            RevoluteJointDef jointDef = new RevoluteJointDef();

            jointDef.CollideConnected = false;
            jointDef.EnableMotor      = true;
            jointDef.MaxMotorTorque   = 0f;

            // Other re-usable stuff .
            const float legRadius       = 0.05f; // Half the thickness of the leg
            Vec2        upperLegPosBase = new Vec2(walkerX, walkerY - 0.25f);
            Vec2        lowerLegPosBase = new Vec2(walkerX, walkerY - 0.75f);

            // ===== Create left leg.
            // Upper leg.
            Body upperLeftLegBody = CreatePole(upperLegPosBase, 0.5f, (float)SysMath.PI, legRadius, 2f, 0x1);

            // Join to torso (hip joint)
            jointDef.Initialize(_torsoBody, upperLeftLegBody, upperLegPosBase);
            _leftHipJoint = (RevoluteJoint)_world.CreateJoint(jointDef);

            // Lower leg.
            _leftLowerLegBody = CreatePole(lowerLegPosBase, __lowerLegLength, (float)SysMath.PI, legRadius, 2f, 0x1);
            // Join to upper leg (knee joint)
            jointDef.Initialize(upperLeftLegBody, _leftLowerLegBody, lowerLegPosBase);
            _leftKneeJoint = (RevoluteJoint)_world.CreateJoint(jointDef);

            // ===== Create right leg.
            // Upper leg.
            Body upperRightLegBody = CreatePole(upperLegPosBase, 0.5f, (float)SysMath.PI, legRadius, 2f, 0x1);

            // Join to torso (hip joint)
            jointDef.Initialize(_torsoBody, upperRightLegBody, upperLegPosBase);
            _rightHipJoint = (RevoluteJoint)_world.CreateJoint(jointDef);

            // Lower leg.
            _rightLowerLegBody = CreatePole(lowerLegPosBase, __lowerLegLength, (float)SysMath.PI, legRadius, 2f, 0x1);
            // Join to upper leg (knee joint)
            jointDef.Initialize(upperRightLegBody, _rightLowerLegBody, lowerLegPosBase);
            _rightKneeJoint = (RevoluteJoint)_world.CreateJoint(jointDef);
        }
Ejemplo n.º 19
0
 /// <summary>
 /// Sample from a binary/Bernoulli distribution with the given probaility of sampling 'true'.
 /// </summary>
 /// <param name="rng">Random number generator.</param>
 /// <param name="probability">Probability of sampling boolean true.</param>
 /// <returns>A boolean random sample.</returns>
 public static bool SampleBernoulli(IRandomSource rng, float probability)
 {
     return(rng.NextFloat() < probability);
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Get a sample from the uniform distribution with interval [0, scale).
 /// </summary>
 public float Sample(float scale)
 {
     return(_rng.NextFloat() * scale);
 }
Ejemplo n.º 21
0
 /// <summary>
 /// Take a sample 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>
 /// <returns>A random sample.</returns>
 public static float Sample(IRandomSource rng, float min, float max)
 {
     Debug.Assert(max >= min);
     return(min + (rng.NextFloat() * (max - min)));
 }
Ejemplo n.º 22
0
 /// <summary>
 /// Take a sample from the uniform distribution with interval [0, 1).
 /// </summary>
 /// <param name="rng">Random source.</param>
 /// <returns>A random sample.</returns>
 public static float Sample(IRandomSource rng)
 {
     return(rng.NextFloat());
 }