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