14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#!/usr/bin/env python
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport unittest
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport random
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport time
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport pickle
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport warnings
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom math import log, exp, pi, fsum, sin
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom functools import reduce
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom test import test_support
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestBasicOps(unittest.TestCase):
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # Superclass with tests common to all generators.
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # Subclasses must arrange for self.gen to retrieve the Random instance
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # to be tested.
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def randomlist(self, n):
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """Helper function to make a list of random numbers"""
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return [self.gen.random() for i in xrange(n)]
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_autoseed(self):
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed()
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        state1 = self.gen.getstate()
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        time.sleep(0.1)
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed()      # diffent seeds at different times
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        state2 = self.gen.getstate()
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertNotEqual(state1, state2)
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_saverestore(self):
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        N = 1000
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed()
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        state = self.gen.getstate()
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        randseq = self.randomlist(N)
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.setstate(state)    # should regenerate the same sequence
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(randseq, self.randomlist(N))
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_seedargs(self):
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for arg in [None, 0, 0L, 1, 1L, -1, -1L, 10**20, -(10**20),
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    3.14, 1+2j, 'a', tuple('abc')]:
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.gen.seed(arg)
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for arg in [range(3), dict(one=1)]:
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertRaises(TypeError, self.gen.seed, arg)
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.gen.seed, 1, 2)
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, type(self.gen), [])
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_jumpahead(self):
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed()
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        state1 = self.gen.getstate()
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.jumpahead(100)
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        state2 = self.gen.getstate()    # s/b distinct from state1
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertNotEqual(state1, state2)
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.jumpahead(100)
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        state3 = self.gen.getstate()    # s/b distinct from state2
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertNotEqual(state2, state3)
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with test_support.check_py3k_warnings(quiet=True):
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertRaises(TypeError, self.gen.jumpahead)  # needs an arg
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertRaises(TypeError, self.gen.jumpahead, 2, 3)  # too many
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_sample(self):
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # For the entire allowable range of 0 <= k <= N, validate that
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # the sample is of the correct length and contains only unique items
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        N = 100
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        population = xrange(N)
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for k in xrange(N+1):
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = self.gen.sample(population, k)
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(len(s), k)
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            uniq = set(s)
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(len(uniq), k)
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(uniq <= set(population))
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.gen.sample([], 0), [])  # test edge case N==k==0
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_sample_distribution(self):
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # For the entire allowable range of 0 <= k <= N, validate that
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # sample generates all possible permutations
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        n = 5
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pop = range(n)
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        trials = 10000  # large num prevents false negatives without slowing normal case
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        def factorial(n):
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return reduce(int.__mul__, xrange(1, n), 1)
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for k in xrange(n):
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            expected = factorial(n) // factorial(n-k)
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            perms = {}
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for i in xrange(trials):
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                perms[tuple(self.gen.sample(pop, k))] = None
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if len(perms) == expected:
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    break
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else:
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.fail()
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_sample_inputs(self):
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # SF bug #801342 -- population can be any iterable defining __len__()
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.sample(set(range(20)), 2)
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.sample(range(20), 2)
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.sample(xrange(20), 2)
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.sample(str('abcdefghijklmnopqrst'), 2)
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.sample(tuple('abcdefghijklmnopqrst'), 2)
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_sample_on_dicts(self):
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.sample(dict.fromkeys('abcdefghijklmnopqrst'), 2)
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # SF bug #1460340 -- random.sample can raise KeyError
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        a = dict.fromkeys(range(10)+range(10,100,2)+range(100,110))
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.sample(a, 3)
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # A followup to bug #1460340:  sampling from a dict could return
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # a subset of its keys or of its values, depending on the size of
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # the subset requested.
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        N = 30
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        d = dict((i, complex(i, i)) for i in xrange(N))
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for k in xrange(N+1):
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            samp = self.gen.sample(d, k)
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # Verify that we got ints back (keys); the values are complex.
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for x in samp:
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                self.assertTrue(type(x) is int)
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        samp.sort()
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(samp, range(N))
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_gauss(self):
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Ensure that the seed() method initializes all the hidden state.  In
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # particular, through 2.2.1 it failed to reset a piece of state used
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # by (and only by) the .gauss() method.
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.gen.seed(seed)
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            x1 = self.gen.random()
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            y1 = self.gen.gauss(0, 1)
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.gen.seed(seed)
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            x2 = self.gen.random()
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            y2 = self.gen.gauss(0, 1)
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(x1, x2)
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(y1, y2)
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_pickling(self):
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        state = pickle.dumps(self.gen)
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        origseq = [self.gen.random() for i in xrange(10)]
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        newgen = pickle.loads(state)
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        restoredseq = [newgen.random() for i in xrange(10)]
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(origseq, restoredseq)
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_bug_1727780(self):
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # verify that version-2-pickles can be loaded
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # fine, whether they are created on 32-bit or 64-bit
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # platforms, and that version-3-pickles load fine.
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        files = [("randv2_32.pck", 780),
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                 ("randv2_64.pck", 866),
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                 ("randv3.pck", 343)]
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for file, value in files:
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            f = open(test_support.findfile(file),"rb")
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            r = pickle.load(f)
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            f.close()
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(r.randrange(1000), value)
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass WichmannHill_TestBasicOps(TestBasicOps):
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    gen = random.WichmannHill()
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_setstate_first_arg(self):
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, self.gen.setstate, (2, None, None))
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_strong_jumpahead(self):
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # tests that jumpahead(n) semantics correspond to n calls to random()
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        N = 1000
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        s = self.gen.getstate()
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.jumpahead(N)
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        r1 = self.gen.random()
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # now do it the slow way
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.setstate(s)
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in xrange(N):
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.gen.random()
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        r2 = self.gen.random()
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(r1, r2)
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_gauss_with_whseed(self):
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Ensure that the seed() method initializes all the hidden state.  In
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # particular, through 2.2.1 it failed to reset a piece of state used
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # by (and only by) the .gauss() method.
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.gen.whseed(seed)
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            x1 = self.gen.random()
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            y1 = self.gen.gauss(0, 1)
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.gen.whseed(seed)
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            x2 = self.gen.random()
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            y2 = self.gen.gauss(0, 1)
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(x1, x2)
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(y1, y2)
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_bigrand(self):
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Verify warnings are raised when randrange is too large for random()
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with warnings.catch_warnings():
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            warnings.filterwarnings("error", "Underlying random")
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertRaises(UserWarning, self.gen.randrange, 2**60)
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass SystemRandom_TestBasicOps(TestBasicOps):
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    gen = random.SystemRandom()
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_autoseed(self):
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Doesn't need to do anything except not fail
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed()
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_saverestore(self):
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(NotImplementedError, self.gen.getstate)
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(NotImplementedError, self.gen.setstate, None)
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_seedargs(self):
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Doesn't need to do anything except not fail
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed(100)
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_jumpahead(self):
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Doesn't need to do anything except not fail
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.jumpahead(100)
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_gauss(self):
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.gauss_next = None
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed(100)
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.gen.gauss_next, None)
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_pickling(self):
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(NotImplementedError, pickle.dumps, self.gen)
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_53_bits_per_float(self):
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # This should pass whenever a C double has 53 bit precision.
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        span = 2 ** 53
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cum = 0
2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in xrange(100):
2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cum |= int(self.gen.random() * span)
2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cum, span-1)
2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_bigrand(self):
2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # The randrange routine should build-up the required number of bits
2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # in stages so that all bit positions are active.
2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        span = 2 ** 500
2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cum = 0
2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in xrange(100):
2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            r = self.gen.randrange(span)
2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(0 <= r < span)
2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cum |= r
2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cum, span-1)
2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_bigrand_ranges(self):
2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            start = self.gen.randrange(2 ** i)
2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            stop = self.gen.randrange(2 ** (i-2))
2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if stop <= start:
2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return
2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(start <= self.gen.randrange(start, stop) < stop)
2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_rangelimits(self):
2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(set(range(start,stop)),
2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                set([self.gen.randrange(start,stop) for i in xrange(100)]))
2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_genrandbits(self):
2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Verify ranges
2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for k in xrange(1, 1000):
2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k)
2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Verify all bits active
2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        getbits = self.gen.getrandbits
2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cum = 0
2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for i in xrange(100):
2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                cum |= getbits(span)
2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(cum, 2**span-1)
2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Verify argument checking
2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.gen.getrandbits)
2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.gen.getrandbits, 1, 2)
2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, self.gen.getrandbits, 0)
2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, self.gen.getrandbits, -1)
2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.gen.getrandbits, 10.1)
2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_randbelow_logic(self, _log=log, int=int):
2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # check bitcount transition points:  2**i and 2**(i+1)-1
2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # show that: k = int(1.001 + _log(n, 2))
2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # is equal to or one greater than the number of bits in n
2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in xrange(1, 1000):
2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            n = 1L << i # check an exact power of two
2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            numbits = i+1
2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            k = int(1.00001 + _log(n, 2))
2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(k, numbits)
2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(n == 2**(k-1))
2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            n += n - 1      # check 1 below the next power of two
2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            k = int(1.00001 + _log(n, 2))
2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertIn(k, [numbits, numbits+1])
2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(2**k > n > 2**(k-2))
2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            n -= n >> 15     # check a little farther below the next power of two
2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            k = int(1.00001 + _log(n, 2))
2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(k, numbits)        # note the stronger assertion
2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(2**k > n > 2**(k-1))   # note the stronger assertion
2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass MersenneTwister_TestBasicOps(TestBasicOps):
3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    gen = random.Random()
3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_setstate_first_arg(self):
3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_setstate_middle_arg(self):
3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Wrong type, s/b tuple
3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Wrong length, s/b 625
3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, self.gen.setstate, (2, (1,2,3), None))
3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Wrong type, s/b tuple of 625 ints
3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.gen.setstate, (2, ('a',)*625, None))
3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Last element s/b an int also
3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.gen.setstate, (2, (0,)*624+('a',), None))
3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_referenceImplementation(self):
3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Compare the python implementation with results from the original
3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # code.  Create 2000 53-bit precision random floats.  Compare only
3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # the last ten entries to show that the independent implementations
3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # are tracking.  Here is the main() function needed to create the
3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # list of expected random numbers:
3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        #    void main(void){
3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        #         int i;
3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        #         unsigned long init[4]={61731, 24903, 614, 42143}, length=4;
3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        #         init_by_array(init, length);
3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        #         for (i=0; i<2000; i++) {
3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        #           printf("%.15f ", genrand_res53());
3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        #           if (i%5==4) printf("\n");
3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        #         }
3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        #     }
3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        expected = [0.45839803073713259,
3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0.86057815201978782,
3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0.92848331726782152,
3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0.35932681119782461,
3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0.081823493762449573,
3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0.14332226470169329,
3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0.084297823823520024,
3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0.53814864671831453,
3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0.089215024911993401,
3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0.78486196105372907]
3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96))
3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        actual = self.randomlist(2000)[-10:]
3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for a, e in zip(actual, expected):
3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertAlmostEqual(a,e,places=14)
3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_strong_reference_implementation(self):
3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Like test_referenceImplementation, but checks for exact bit-level
3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # equality.  This should pass on any box where C double contains
3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # at least 53 bits of precision (the underlying algorithm suffers
3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # no rounding errors -- all results are exact).
3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        from math import ldexp
3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        expected = [0x0eab3258d2231fL,
3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0x1b89db315277a5L,
3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0x1db622a5518016L,
3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0x0b7f9af0d575bfL,
3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0x029e4c4db82240L,
3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0x04961892f5d673L,
3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0x02b291598e4589L,
3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0x11388382c15694L,
3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0x02dad977c9e1feL,
3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    0x191d96d4d334c6L]
3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96))
3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        actual = self.randomlist(2000)[-10:]
3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for a, e in zip(actual, expected):
3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(long(ldexp(a, 53)), e)
3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_long_seed(self):
3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # This is most interesting to run in debug mode, just to make sure
3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # nothing blows up.  Under the covers, a dynamically resized array
3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # is allocated, consuming space proportional to the number of bits
3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # in the seed.  Unfortunately, that's a quadratic-time algorithm,
3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # so don't make this horribly big.
3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        seed = (1L << (10000 * 8)) - 1  # about 10K bytes
3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed(seed)
3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_53_bits_per_float(self):
3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # This should pass whenever a C double has 53 bit precision.
3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        span = 2 ** 53
3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cum = 0
3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in xrange(100):
3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cum |= int(self.gen.random() * span)
3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cum, span-1)
3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_bigrand(self):
3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # The randrange routine should build-up the required number of bits
3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # in stages so that all bit positions are active.
3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        span = 2 ** 500
3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cum = 0
3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in xrange(100):
3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            r = self.gen.randrange(span)
3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(0 <= r < span)
3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cum |= r
3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cum, span-1)
3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_bigrand_ranges(self):
3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            start = self.gen.randrange(2 ** i)
3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            stop = self.gen.randrange(2 ** (i-2))
4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if stop <= start:
4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return
4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(start <= self.gen.randrange(start, stop) < stop)
4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_rangelimits(self):
4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(set(range(start,stop)),
4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                set([self.gen.randrange(start,stop) for i in xrange(100)]))
4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_genrandbits(self):
4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Verify cross-platform repeatability
4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.gen.seed(1234567)
4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(self.gen.getrandbits(100),
4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         97904845777343510404718956115L)
4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Verify ranges
4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for k in xrange(1, 1000):
4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k)
4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Verify all bits active
4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        getbits = self.gen.getrandbits
4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cum = 0
4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for i in xrange(100):
4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                cum |= getbits(span)
4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(cum, 2**span-1)
4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Verify argument checking
4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.gen.getrandbits)
4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.gen.getrandbits, 'a')
4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, self.gen.getrandbits, 1, 2)
4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, self.gen.getrandbits, 0)
4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, self.gen.getrandbits, -1)
4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_randbelow_logic(self, _log=log, int=int):
4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # check bitcount transition points:  2**i and 2**(i+1)-1
4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # show that: k = int(1.001 + _log(n, 2))
4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # is equal to or one greater than the number of bits in n
4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in xrange(1, 1000):
4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            n = 1L << i # check an exact power of two
4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            numbits = i+1
4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            k = int(1.00001 + _log(n, 2))
4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(k, numbits)
4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(n == 2**(k-1))
4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            n += n - 1      # check 1 below the next power of two
4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            k = int(1.00001 + _log(n, 2))
4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertIn(k, [numbits, numbits+1])
4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(2**k > n > 2**(k-2))
4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            n -= n >> 15     # check a little farther below the next power of two
4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            k = int(1.00001 + _log(n, 2))
4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertEqual(k, numbits)        # note the stronger assertion
4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(2**k > n > 2**(k-1))   # note the stronger assertion
4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_randrange_bug_1590891(self):
4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        start = 1000000000000
4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        stop = -100000000000000000000
4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        step = -200
4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        x = self.gen.randrange(start, stop, step)
4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(stop < x <= start)
4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual((x+stop)%step, 0)
4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef gamma(z, sqrt2pi=(2.0*pi)**0.5):
4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # Reflection to right half of complex plane
4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if z < 0.5:
4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return pi / sin(pi*z) / gamma(1.0-z)
4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # Lanczos approximation with g=7
4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    az = z + (7.0 - 0.5)
4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return az ** (z-0.5) / exp(az) * sqrt2pi * fsum([
4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0.9999999999995183,
4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        676.5203681218835 / z,
4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        -1259.139216722289 / (z+1.0),
4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        771.3234287757674 / (z+2.0),
4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        -176.6150291498386 / (z+3.0),
4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        12.50734324009056 / (z+4.0),
4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        -0.1385710331296526 / (z+5.0),
4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0.9934937113930748e-05 / (z+6.0),
4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        0.1659470187408462e-06 / (z+7.0),
4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ])
4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestDistributions(unittest.TestCase):
4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_zeroinputs(self):
4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Verify that distributions can handle a series of zero inputs'
4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g = random.Random()
4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        x = [g.random() for i in xrange(50)] + [0.0]*5
4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.uniform(1,10)
4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.paretovariate(1.0)
4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.expovariate(1.0)
4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.weibullvariate(1.0, 1.0)
4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.normalvariate(0.0, 1.0)
4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.gauss(0.0, 1.0)
4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.lognormvariate(0.0, 1.0)
4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.vonmisesvariate(0.0, 1.0)
4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.gammavariate(0.01, 1.0)
4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.gammavariate(1.0, 1.0)
4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.gammavariate(200.0, 1.0)
4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.betavariate(3.0, 3.0)
4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g.random = x[:].pop; g.triangular(0.0, 1.0, 1.0/3.0)
4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_avg_std(self):
5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Use integration to test distribution average and standard deviation.
5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Only works for distributions which do not consume variates in pairs
5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        g = random.Random()
5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        N = 5000
5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        x = [i/float(N) for i in xrange(1,N)]
5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for variate, args, mu, sigmasqrd in [
5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)**2/12),
5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (g.triangular, (0.0, 1.0, 1.0/3.0), 4.0/9.0, 7.0/9.0/18.0),
5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (g.expovariate, (1.5,), 1/1.5, 1/1.5**2),
5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (g.paretovariate, (5.0,), 5.0/(5.0-1),
5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  5.0/((5.0-1)**2*(5.0-2))),
5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (g.weibullvariate, (1.0, 3.0), gamma(1+1/3.0),
5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  gamma(1+2/3.0)-gamma(1+1/3.0)**2) ]:
5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            g.random = x[:].pop
5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            y = []
5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for i in xrange(len(x)):
5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                try:
5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    y.append(variate(*args))
5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                except IndexError:
5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    pass
5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s1 = s2 = 0
5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for e in y:
5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s1 += e
5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                s2 += (e - mu) ** 2
5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            N = len(y)
5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertAlmostEqual(s1/N, mu, 2)
5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertAlmostEqual(s2/(N-1), sigmasqrd, 2)
5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestModule(unittest.TestCase):
5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def testMagicConstants(self):
5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141)
5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertAlmostEqual(random.TWOPI, 6.28318530718)
5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertAlmostEqual(random.LOG4, 1.38629436111989)
5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertAlmostEqual(random.SG_MAGICCONST, 2.50407739677627)
5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test__all__(self):
5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # tests validity but not completeness of the __all__ list
5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(set(random.__all__) <= set(dir(random)))
5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_random_subclass_with_kwargs(self):
5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # SF bug #1486663 -- this used to erroneously raise a TypeError
5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class Subclass(random.Random):
5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            def __init__(self, newarg=None):
5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                random.Random.__init__(self)
5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Subclass(newarg=1)
5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_main(verbose=None):
5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    testclasses =    [WichmannHill_TestBasicOps,
5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      MersenneTwister_TestBasicOps,
5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      TestDistributions,
5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      TestModule]
5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    try:
5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        random.SystemRandom().random()
5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    except NotImplementedError:
5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pass
5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else:
5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        testclasses.append(SystemRandom_TestBasicOps)
5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_support.run_unittest(*testclasses)
5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # verify reference counting
5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    import sys
5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if verbose and hasattr(sys, "gettotalrefcount"):
5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        counts = [None] * 5
5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in xrange(len(counts)):
5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            test_support.run_unittest(*testclasses)
5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            counts[i] = sys.gettotalrefcount()
5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        print counts
5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__":
5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_main(verbose=True)
573