コード例 #1
0
        internal static ulong rk_interval(ulong max, rk_state state)
        {
            ulong mask = max, value;

            if (max == 0)
            {
                return(0);
            }
            /* Smallest bit mask >= max */
            mask |= mask >> 1;
            mask |= mask >> 2;
            mask |= mask >> 4;
            mask |= mask >> 8;
            mask |= mask >> 16;
            mask |= mask >> 32;

            /* Search a random value in [0..mask] <= max */
            if (max <= 0xffffffffUL)
            {
                while ((value = (rk_random(state) & mask)) > max)
                {
                    ;
                }
            }
            else
            {
                while ((value = (rk_ulong(state) & mask)) > max)
                {
                    ;
                }
            }

            return(value);
        }
コード例 #2
0
        static long rk_poisson_ptrs(rk_state state, double lam)
        {
            long   k;
            double U, V, slam, loglam, a, b, invalpha, vr, us;

            slam     = Math.Sqrt(lam);
            loglam   = Math.Log(lam);
            b        = 0.931 + 2.53 * slam;
            a        = -0.059 + 0.02483 * b;
            invalpha = 1.1239 + 1.1328 / (b - 3.4);
            vr       = 0.9277 - 3.6224 / (b - 2);

            while (true)
            {
                U  = rk_double(state) - 0.5;
                V  = rk_double(state);
                us = 0.5 - Math.Abs(U);
                k  = (long)Math.Floor((2 * a / us + b) * U + lam + 0.43);
                if ((us >= 0.07) && (V <= vr))
                {
                    return(k);
                }
                if ((k < 0) ||
                    ((us < 0.013) && (V > us)))
                {
                    continue;
                }
                if ((Math.Log(V) + Math.Log(invalpha) - Math.Log(a / (us * us) + b)) <=
                    (-lam + k * loglam - loggam(k + 1)))
                {
                    return(k);
                }
            }
        }
コード例 #3
0
        internal static long rk_logseries(rk_state state, double p)
        {
            double q, r, U, V;
            long   result;

            r = Math.Log(1.0 - p);

            while (true)
            {
                V = rk_double(state);
                if (V >= p)
                {
                    return(1);
                }
                U = rk_double(state);
                q = 1.0 - Math.Exp(r * U);
                if (V <= q * q)
                {
                    result = (long)Math.Floor(1 + Math.Log(V) / Math.Log(q));
                    if (result < 1)
                    {
                        continue;
                    }
                    else
                    {
                        return(result);
                    }
                }
                if (V >= q)
                {
                    return(1);
                }
                return(2);
            }
        }
コード例 #4
0
        internal static double rk_logistic(rk_state state, double loc, double scale)
        {
            double U;

            U = rk_double(state);
            return(loc + scale * Math.Log(U / (1.0 - U)));
        }
コード例 #5
0
        internal static double rk_gumbel(rk_state state, double loc, double scale)
        {
            double U;

            U = 1.0 - rk_double(state);
            return(loc - scale * Math.Log(-Math.Log(U)));
        }
コード例 #6
0
        internal static long rk_negative_binomial(rk_state state, double n, double p)
        {
            double Y;

            Y = rk_gamma(state, n, (1 - p) / p);
            return(rk_poisson(state, Y));
        }
コード例 #7
0
        internal static double rk_gauss(rk_state state)
        {
            if (state.has_gauss)
            {
                double tmp = state.gauss;
                state.gauss     = 0;
                state.has_gauss = false;
                return(tmp);
            }
            else
            {
                double f, x1, x2, r2;

                do
                {
                    x1 = 2.0 * rk_double(state) - 1.0;
                    x2 = 2.0 * rk_double(state) - 1.0;
                    r2 = x1 * x1 + x2 * x2;
                }while (r2 >= 1.0 || r2 == 0.0);

                /* Box-Muller transform */
                f = Math.Sqrt(-2.0 * Math.Log(r2) / r2);
                /* Keep for next call */
                state.gauss     = f * x1;
                state.has_gauss = true;
                return(f * x2);
            }
        }
コード例 #8
0
        static UInt64 rk_uint64(rk_state state)
        {
            UInt64 upper = (UInt64)rk_random(state) << 32;
            UInt64 lower = (UInt64)rk_random(state);

            return(upper | lower);
        }
コード例 #9
0
        internal static long rk_zipf(rk_state state, double a)
        {
            double am1, b;

            am1 = a - 1.0;
            b   = Math.Pow(2.0, am1);
            while (true)
            {
                double T, U, V, X;

                U = 1.0 - rk_double(state);
                V = rk_double(state);
                X = Math.Floor(Math.Pow(U, -1.0 / am1));

                /*
                 * The real result may be above what can be represented in a signed
                 * long. Since this is a straightforward rejection algorithm, we can
                 * just reject this value. This function then models a Zipf
                 * distribution truncated to sys.maxint.
                 */
                if (X > Int64.MaxValue || X < 1.0)
                {
                    continue;
                }

                T = Math.Pow(1.0 + 1.0 / X, am1);
                if (V * X * (T - 1.0) / (b - 1.0) <= T / b)
                {
                    return((long)X);
                }
            }
        }
コード例 #10
0
        /*
         * Fills an array with cnt random npy_bool between off and off + rng
         * inclusive.
         */
        internal static void rk_random_bool(bool off, bool rng, npy_intp cnt,
                                            bool[] _out, rk_state state)
        {
            npy_intp i;
            UInt32   buf  = 0;
            int      bcnt = 0;

            if (rng == false)
            {
                for (i = 0; i < cnt; i++)
                {
                    _out[i] = off;
                }
                return;
            }

            /* If we reach here rng and mask are one and off is zero */
            System.Diagnostics.Debug.Assert(rng == true && off == false);
            for (i = 0; i < cnt; i++)
            {
                if (bcnt == 0)
                {
                    buf  = rk_uint32(state);
                    bcnt = 31;
                }
                else
                {
                    buf >>= 1;
                    bcnt--;
                }
                _out[i] = (buf & 0x00000001) != 0;
            }
        }
コード例 #11
0
        /*
         * Fills an array with cnt random npy_uint32 between off and off + rng
         * inclusive. The numbers wrap if rng is sufficiently large.
         */
        internal static void rk_random_uint32(UInt32 off, UInt32 rng, npy_intp cnt,
                                              UInt32[] _out, rk_state state)
        {
            UInt32   val, mask = rng;
            npy_intp i;

            if (rng == 0)
            {
                for (i = 0; i < cnt; i++)
                {
                    _out[i] = off;
                }
                return;
            }

            /* Smallest bit mask >= max */
            mask |= mask >> 1;
            mask |= mask >> 2;
            mask |= mask >> 4;
            mask |= mask >> 8;
            mask |= mask >> 16;

            for (i = 0; i < cnt; i++)
            {
                while ((val = (rk_uint32(state) & mask)) > rng)
                {
                    ;
                }
                _out[i] = off + val;
            }
        }
コード例 #12
0
        static long rk_hypergeometric_hyp(rk_state state, long good, long bad, long sample)
        {
            long   d1, K, Z;
            double d2, U, Y;

            d1 = bad + good - sample;
            d2 = (double)Math.Min(bad, good);

            Y = d2;
            K = sample;
            while (Y > 0.0)
            {
                U  = rk_double(state);
                Y -= (long)Math.Floor(U + Y / (d1 + K));
                K--;
                if (K == 0)
                {
                    break;
                }
            }
            Z = (long)(d2 - Y);
            if (good > bad)
            {
                Z = sample - Z;
            }
            return(Z);
        }
コード例 #13
0
        static Int64 rk_int64(rk_state state)
        {
            Int64 upper = (Int64)rk_random(state) << 32;
            Int64 lower = (Int64)rk_random(state);

            return(upper | lower);
        }
コード例 #14
0
        internal static long rk_binomial(rk_state state, long n, double p)
        {
            double q;

            if (p <= 0.5)
            {
                if (p * n <= 30.0)
                {
                    return(rk_binomial_inversion(state, n, p));
                }
                else
                {
                    return(rk_binomial_btpe(state, n, p));
                }
            }
            else
            {
                q = 1.0 - p;
                if (q * n <= 30.0)
                {
                    return(n - rk_binomial_inversion(state, n, q));
                }
                else
                {
                    return(n - rk_binomial_btpe(state, n, q));
                }
            }
        }
コード例 #15
0
        internal static void rk_fill(byte[] buffer, Int32 size, rk_state state)
        {
            ulong r;

            int index = 0;

            for (; size >= 4; size -= 4)
            {
                r = rk_random(state);
                buffer[index++] = (byte)(r & 0xFF);
                buffer[index++] = (byte)((r >> 8) & 0xFF);
                buffer[index++] = (byte)((r >> 16) & 0xFF);
                buffer[index++] = (byte)((r >> 24) & 0xFF);
            }

            if (size <= 0)
            {
                return;
            }
            r = rk_random(state);
            for (; size > 0; r >>= 8, size--)
            {
                buffer[index++] = (byte)(r & 0xFF);
            }
        }
コード例 #16
0
        internal static double rk_standard_gamma(rk_state state, double shape)
        {
            double b, c;
            double U, V, X, Y;

            if (shape == 1.0)
            {
                return(rk_standard_exponential(state));
            }
            else if (shape < 1.0)
            {
                for (; ;)
                {
                    U = rk_double(state);
                    V = rk_standard_exponential(state);
                    if (U <= 1.0 - shape)
                    {
                        X = Math.Pow(U, 1.0 / shape);
                        if (X <= V)
                        {
                            return(X);
                        }
                    }
                    else
                    {
                        Y = -Math.Log((1 - U) / shape);
                        X = Math.Pow(1.0 - shape + shape * Y, 1.0 / shape);
                        if (X <= (V + Y))
                        {
                            return(X);
                        }
                    }
                }
            }
            else
            {
                b = shape - 1.0 / 3.0;
                c = 1.0 / Math.Sqrt(9 * b);
                for (; ;)
                {
                    do
                    {
                        X = rk_gauss(state);
                        V = 1.0 + c * X;
                    } while (V <= 0.0);

                    V = V * V * V;
                    U = rk_double(state);
                    if (U < 1.0 - 0.0331 * (X * X) * (X * X))
                    {
                        return(b * V);
                    }
                    if (Math.Log(U) < 0.5 * X * X + b * (1.0 - V + Math.Log(V)))
                    {
                        return(b * V);
                    }
                }
            }
        }
コード例 #17
0
        public static void rk_seed(ulong seed, rk_state state)
        {
            state.gauss        = 0;
            state.has_gauss    = false;
            state.has_binomial = false;

            state.rndGenerator.Seed(seed, state);
        }
コード例 #18
0
        internal static double rk_weibull(rk_state state, double a)
        {
            if (a == 0.0)
            {
                return(0.0);
            }

            return(Math.Pow(rk_standard_exponential(state), 1.0 / a));
        }
コード例 #19
0
        internal static double rk_standard_t(rk_state state, double df)
        {
            double N, G, X;

            N = rk_gauss(state);
            G = rk_standard_gamma(state, df / 2);
            X = Math.Sqrt(df / 2) * N / Math.Sqrt(G);
            return(X);
        }
コード例 #20
0
 internal static long rk_hypergeometric(rk_state state, long good, long bad, long sample)
 {
     if (sample > 10)
     {
         return(rk_hypergeometric_hrua(state, good, bad, sample));
     }
     else
     {
         return(rk_hypergeometric_hyp(state, good, bad, sample));
     }
 }
コード例 #21
0
 internal static long rk_geometric(rk_state state, double p)
 {
     if (p >= 0.333333333333333333333333)
     {
         return(rk_geometric_search(state, p));
     }
     else
     {
         return(rk_geometric_inversion(state, p));
     }
 }
コード例 #22
0
        internal static double rk_laplace(rk_state state, double loc, double scale)
        {
            double U;

            U = rk_double(state);
            if (U < 0.5)
            {
                U = loc + scale * Math.Log(U + U);
            }
            else
            {
                U = loc - scale * Math.Log(2.0 - U - U);
            }
            return(U);
        }
コード例 #23
0
 internal static long rk_poisson(rk_state state, double lam)
 {
     if (lam >= 10)
     {
         return(rk_poisson_ptrs(state, lam));
     }
     else if (lam == 0)
     {
         return(0);
     }
     else
     {
         return(rk_poisson_mult(state, lam));
     }
 }
コード例 #24
0
        static long rk_geometric_search(rk_state state, double p)
        {
            double U;
            long   X;
            double sum, prod, q;

            X   = 1;
            sum = prod = p;
            q   = 1.0 - p;
            U   = rk_double(state);
            while (U > sum)
            {
                prod *= q;
                sum  += prod;
                X++;
            }
            return(X);
        }
コード例 #25
0
 internal static double rk_noncentral_chisquare(rk_state state, double df, double nonc)
 {
     if (nonc == 0)
     {
         return(rk_chisquare(state, df));
     }
     if (1 < df)
     {
         double Chi2 = rk_chisquare(state, df - 1);
         double N    = rk_gauss(state) + Math.Sqrt(nonc);
         return(Chi2 + N * N);
     }
     else
     {
         long i = rk_poisson(state, nonc / 2.0);
         return(rk_chisquare(state, df + 2 * i));
     }
 }
コード例 #26
0
        static long rk_binomial_inversion(rk_state state, long n, double p)
        {
            double q, qn, np, px, U;
            long   X, bound;

            if (!(state.has_binomial) ||
                (state.nsave != n) ||
                (state.psave != p))
            {
                state.nsave        = n;
                state.psave        = p;
                state.has_binomial = true;
                state.q            = q = 1.0 - p;
                state.r            = qn = Math.Exp(n * Math.Log(q));
                state.c            = np = n * p;
                state.m            = bound = (npy_intp)Math.Min(n, np + 10.0 * Math.Sqrt(np * q + 1));
            }
            else
            {
                q     = state.q;
                qn    = state.r;
                np    = state.c;
                bound = state.m;
            }
            X  = 0;
            px = qn;
            U  = rk_double(state);
            while (U > px)
            {
                X++;
                if (X > bound)
                {
                    X  = 0;
                    px = qn;
                    U  = rk_double(state);
                }
                else
                {
                    U -= px;
                    px = ((n - X + 1) * p * px) / (X * q);
                }
            }
            return(X);
        }
コード例 #27
0
        /*
         * Fills an array with cnt random npy_int64 between off and off + rng
         * inclusive. The numbers wrap if rng is sufficiently large.
         */
        internal static void rk_random_int64(Int64 off, Int64 rng, npy_intp cnt,
                                             Int64[] _out, rk_state state)
        {
            Int64    val, mask = rng;
            npy_intp i;

            if (rng == 0)
            {
                for (i = 0; i < cnt; i++)
                {
                    _out[i] = off;
                }
                return;
            }

            /* Smallest bit mask >= max */
            mask |= mask >> 1;
            mask |= mask >> 2;
            mask |= mask >> 4;
            mask |= mask >> 8;
            mask |= mask >> 16;
            mask |= mask >> 32;


            for (i = 0; i < cnt; i++)
            {
                if (rng <= 0xffffffffL)
                {
                    while ((val = (rk_int32(state) & mask)) > rng)
                    {
                        ;
                    }
                }
                else
                {
                    while ((val = (rk_int64(state) & mask)) > rng)
                    {
                        ;
                    }
                }
                _out[i] = off + val;
            }
        }
コード例 #28
0
        internal static double rk_wald(rk_state state, double mean, double scale)
        {
            double U, X, Y;
            double mu_2l;

            mu_2l = mean / (2 * scale);
            Y     = rk_gauss(state);
            Y     = mean * Y * Y;
            X     = mean + mu_2l * (Y - Math.Sqrt(4 * scale * Y + Y * Y));
            U     = rk_double(state);
            if (U <= mean / (mean + X))
            {
                return(X);
            }
            else
            {
                return(mean * mean / X);
            }
        }
コード例 #29
0
        /*
         * Fills an array with cnt random npy_uint16 between off and off + rng
         * inclusive. The numbers wrap if rng is sufficiently large.
         */
        internal static void rk_random_uint16(UInt16 off, UInt16 rng, npy_intp cnt,
                                              UInt16[] _out, rk_state state)
        {
            UInt16   val, mask = rng;
            npy_intp i;
            UInt32   buf  = 0;
            int      bcnt = 0;

            if (rng == 0)
            {
                for (i = 0; i < cnt; i++)
                {
                    _out[i] = off;
                }
                return;
            }

            /* Smallest bit mask >= max */
            mask |= (UInt16)(mask >> 1);
            mask |= (UInt16)(mask >> 2);
            mask |= (UInt16)(mask >> 4);
            mask |= (UInt16)(mask >> 8);

            for (i = 0; i < cnt; i++)
            {
                do
                {
                    if (bcnt == 0)
                    {
                        buf  = rk_uint32(state);
                        bcnt = 1;
                    }
                    else
                    {
                        buf >>= 16;
                        bcnt--;
                    }
                    val = (UInt16)(buf & mask);
                } while (val > rng);
                _out[i] = (UInt16)(off + val);
            }
        }
コード例 #30
0
        internal static double rk_beta(rk_state state, double a, double b)
        {
            double Ga, Gb;

            if ((a <= 1.0) && (b <= 1.0))
            {
                double U, V, X, Y;
                /* Use Johnk's algorithm */

                while (true)
                {
                    U = rk_double(state);
                    V = rk_double(state);
                    X = Math.Pow(U, 1.0 / a);
                    Y = Math.Pow(V, 1.0 / b);

                    if ((X + Y) <= 1.0)
                    {
                        if (X + Y > 0)
                        {
                            return(X / (X + Y));
                        }
                        else
                        {
                            double logX = Math.Log(U) / a;
                            double logY = Math.Log(V) / b;
                            double logM = logX > logY ? logX : logY;
                            logX -= logM;
                            logY -= logM;

                            return(Math.Exp(logX - Math.Log(Math.Exp(logX) + Math.Exp(logY))));
                        }
                    }
                }
            }
            else
            {
                Ga = rk_standard_gamma(state, a);
                Gb = rk_standard_gamma(state, b);
                return(Ga / (Ga + Gb));
            }
        }