Пример #1
0
        public double GetNext(Random rng)
        {
            double u, v, z;

            while (true)
            {
                // generate a candidate point
                do
                {
                    z = normalGenerator.GetNext(rng);
                    v = 1.0 + a2 * z;
                } while (v <= 0.0);
                v = v * v * v;
                u = rng.NextDouble();

                // check whether the point is outside the acceptance region
                // first via a simple interrior squeeze
                double z2 = z * z; double z4 = z2 * z2;
                if (u > 1.0 - 0.331 * z4)
                {
                    // then, if necessary, via the exact rejection boundary
                    if (Math.Log(u) > z2 / 2.0 + a1 * (1.0 - v + Math.Log(v)))
                    {
                        continue;
                    }
                }

                return(a1 * v);
            }
        }
Пример #2
0
        /// <inheritdoc />
        public override double GetRandomValue(Random rng)
        {
            if (rng == null)
            {
                throw new ArgumentNullException(nameof(rng));
            }

            // This is a rather weird transformation generator described in Michael et al, "Generating Random Variates
            // Using Transformations with Multiple Roots", The American Statistician 30 (1976) 88-90.

            // u ~ U(0,1), v ~ ChiSquare(1), i.e. square of standard normal deviate

            double v = MoreMath.Sqr(rngGenerator.GetNext(rng));
            double w = mu * v;
            double x = mu * (1.0 + (w - Math.Sqrt((4.0 * lambda + w) * w)) / (2.0 * lambda));
            double u = rng.NextDouble();

            if (u <= mu / (mu + x))
            {
                return(x);
            }
            else
            {
                return(mu * mu / x);
            }
        }
Пример #3
0
        public double GetNext(Random rng)
        {
            double x = alphaGenerator.GetNext(rng);
            double y = betaGenerator.GetNext(rng);

            return(x / (x + y));
        }
Пример #4
0
 /// <inheritdoc />
 public override double GetRandomValue(Random rng)
 {
     if (rng == null)
     {
         throw new ArgumentNullException("rng");
     }
     return(s * gammaRng.GetNext(rng));
 }
Пример #5
0
 /// <inheritdoc />
 public override double GetRandomValue(Random rng)
 {
     if (rng == null)
     {
         throw new ArgumentNullException(nameof(rng));
     }
     return(betaRng.GetNext(rng));
 }
Пример #6
0
        // There is a long and rich history of algorithms for Poisson deviate generation.
        // See Hoermann https://pdfs.semanticscholar.org/00f1/8468dd53e4e3f0c28a5d504f8cd10376a673.pdf for a summary.

        // The simplest generation method besides inversion is to make use the definition of a poisson process and
        // count the number of random numbers needed before their product is less than e^{-\lambda} (or their sum
        // exceeds \lambda). This is fast for very low \lambda (less than ~3), but time (and number of uniform
        // deviates consumed) clearly scales linearly with \lambda, so it rapidly becomes untentable for larger \lambda.

        // Ahrens and Dieter, "Computer generation of Poisson deviates from modified normal distributions",
        // ACM Transactions on Mathematical Software 8 (1982) 163-179 presented the first O(1) generator, PD.
        // The code is complicated and requires normal deviates as inputs.

        // We use Hermann's PTRS generator.

        // NR contains a ratio-of-uniforms variant with no citation and a squeeze I don't recognize. It isn't
        // as fast as PTRS, though.

        // For intermediate value of \lambda (say ~3 to ~30), the fastest method is actually an optimized
        // form of simple inversion: binary search, starting from the median, using a pre-computed table
        // of CDF values that covers most of the space.

        /// <inheritdoc />
        public override int GetRandomValue(Random rng)
        {
            if (rng is null)
            {
                throw new ArgumentNullException(nameof(rng));
            }
            return(poissonGenerator.GetNext(rng));
        }
        /// <inheritdoc />
        public override double GetRandomValue(Random rng)
        {
            if (rng == null)
            {
                throw new ArgumentNullException(nameof(rng));
            }
            double z = normalRng.GetNext(rng);

            return(mu + sigma * z);
        }
Пример #8
0
        /// <inheritdoc />
        public override double GetRandomValue(Random rng)
        {
            if (rng == null)
            {
                throw new ArgumentNullException(nameof(rng));
            }
            double z = cauchyRng.GetNext(rng);

            return(mu + z * gamma);
        }
Пример #9
0
        /// <inheritdoc />
        public override double GetRandomValue(Random rng)
        {
            // This is a rather weird transformation generator described in Michael et al, "Generating Random Variates
            // Using Transformations with Multiple Roots", The American Statistician 30 (1976) 88-90.

            double u   = rngGenerator.GetNext(rng);
            double y   = MoreMath.Sqr(rngGenerator.GetNext(rng));
            double muy = mu * y;
            double x   = mu * (1.0 + (muy - Math.Sqrt((4.0 * lambda + muy) * muy)) / (2.0 * lambda));
            double z   = rng.NextDouble();

            if (z <= mu / (mu + x))
            {
                return(x);
            }
            else
            {
                return(mu * mu / x);
            }
        }
Пример #10
0
        /// <inheritdoc/>
        public override double GetRandomValue(Random rng)
        {
            if (rng == null)
            {
                throw new ArgumentNullException(nameof(rng));
            }
            double mu = Math.Sqrt(lambda / nu);
            double x  = 0.0;

            for (int k = 0; k < nu; k++)
            {
                x += MoreMath.Sqr(mu + zRng.GetNext(rng));
            }
            return(x);
        }