Пример #1
0
        /*
         *  Random variates from the hypergeometric distribution.
         *
         *  Returns the number of white balls drawn when kk balls
         *  are drawn at random from an urn containing nn1 white
         *  and nn2 black balls.
         */
        private static double RHyper(long kk, double nn1, double nn2, CoinFlipper coins)
        {
            var prng = new PRNG(coins);

            if (kk > 10)
            {
                return(HypergeometricHRUA(prng, nn1, nn2, kk));
            }
            else
            {
                return(HypergeometricHYP(prng, nn1, nn2, kk));
            }
        }
Пример #2
0
        internal static long SampleUniform(ValueRange valueRange, CoinFlipper coins)
        {
            var currentRange = valueRange.Copy();

            if (currentRange.Size() == 0)
            {
                throw new Exception("");
            }
            while (currentRange.Size() > 1)
            {
                var mid = (currentRange.Start + currentRange.End) / 2;
                var bit = coins.GetCoin();
                if (bit)
                {
                    currentRange.Start = mid + 1;
                }
                else
                {
                    currentRange.End = mid;
                }
            }
            return(currentRange.Start);
        }
Пример #3
0
 public PRNG(CoinFlipper coins)
 {
     _coins = coins;
 }
Пример #4
0
        /*
         * Get a sample from the hypergeometric distribution, using the provided bit list as a source of randomness
         */
        internal static long SampleHGD(ValueRange inRange, ValueRange outRange, long mid, CoinFlipper coins)
        {
            var inSize  = inRange.Size();
            var outSize = outRange.Size();

            if (inSize < 0 || outSize < 0 || inSize > outSize || !outRange.Contains(mid))
            {
                throw new ArgumentException();
            }

            var nSampleIndex = mid - outRange.Start + 1;

            if (inSize == outSize)
            {
                return(inRange.Start + nSampleIndex - 1);
            }

            double inSampleNum = RHyper(nSampleIndex, inSize, outSize - inSize, coins);

            if (inSampleNum == 0)
            {
                return(inRange.Start);
            }
            else
            {
                var inSample = inRange.Start + inSampleNum - 1;
                if (!inRange.Contains(Convert.ToInt32(inSample)))
                {
                    throw new ArgumentException();
                }
                return(Convert.ToInt32(inSample));
            }
        }