14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao#!/usr/bin/env python 24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport unittest 44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport random 54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport time 64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport pickle 74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport warnings 84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom math import log, exp, pi, fsum, sin 94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom functools import reduce 104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom test import test_support 114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestBasicOps(unittest.TestCase): 134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Superclass with tests common to all generators. 144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Subclasses must arrange for self.gen to retrieve the Random instance 154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # to be tested. 164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def randomlist(self, n): 184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """Helper function to make a list of random numbers""" 194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return [self.gen.random() for i in xrange(n)] 204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_autoseed(self): 224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed() 234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao state1 = self.gen.getstate() 244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao time.sleep(0.1) 254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed() # diffent seeds at different times 264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao state2 = self.gen.getstate() 274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertNotEqual(state1, state2) 284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_saverestore(self): 304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao N = 1000 314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed() 324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao state = self.gen.getstate() 334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao randseq = self.randomlist(N) 344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.setstate(state) # should regenerate the same sequence 354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(randseq, self.randomlist(N)) 364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_seedargs(self): 384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for arg in [None, 0, 0L, 1, 1L, -1, -1L, 10**20, -(10**20), 394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3.14, 1+2j, 'a', tuple('abc')]: 404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed(arg) 414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for arg in [range(3), dict(one=1)]: 424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.seed, arg) 434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.seed, 1, 2) 444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, type(self.gen), []) 454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_jumpahead(self): 474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed() 484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao state1 = self.gen.getstate() 494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.jumpahead(100) 504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao state2 = self.gen.getstate() # s/b distinct from state1 514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertNotEqual(state1, state2) 524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.jumpahead(100) 534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao state3 = self.gen.getstate() # s/b distinct from state2 544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertNotEqual(state2, state3) 554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao with test_support.check_py3k_warnings(quiet=True): 574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.jumpahead) # needs an arg 584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.jumpahead, 2, 3) # too many 594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_jumpahead_produces_valid_state(self): 614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # From http://bugs.python.org/issue14591. 624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed(199210368) 634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.jumpahead(13550674232554645900) 644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in range(500): 654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao val = self.gen.random() 664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertLess(val, 1.0) 674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_sample(self): 694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # For the entire allowable range of 0 <= k <= N, validate that 704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the sample is of the correct length and contains only unique items 714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao N = 100 724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao population = xrange(N) 734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for k in xrange(N+1): 744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = self.gen.sample(population, k) 754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(s), k) 764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao uniq = set(s) 774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(uniq), k) 784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(uniq <= set(population)) 794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(self.gen.sample([], 0), []) # test edge case N==k==0 804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_sample_distribution(self): 824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # For the entire allowable range of 0 <= k <= N, validate that 834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # sample generates all possible permutations 844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n = 5 854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pop = range(n) 864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao trials = 10000 # large num prevents false negatives without slowing normal case 874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def factorial(n): 884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return reduce(int.__mul__, xrange(1, n), 1) 894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for k in xrange(n): 904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = factorial(n) // factorial(n-k) 914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao perms = {} 924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(trials): 934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao perms[tuple(self.gen.sample(pop, k))] = None 944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if len(perms) == expected: 954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao break 964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.fail() 984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_sample_inputs(self): 1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # SF bug #801342 -- population can be any iterable defining __len__() 1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.sample(set(range(20)), 2) 1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.sample(range(20), 2) 1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.sample(xrange(20), 2) 1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.sample(str('abcdefghijklmnopqrst'), 2) 1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.sample(tuple('abcdefghijklmnopqrst'), 2) 1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_sample_on_dicts(self): 1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.sample(dict.fromkeys('abcdefghijklmnopqrst'), 2) 1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # SF bug #1460340 -- random.sample can raise KeyError 1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = dict.fromkeys(range(10)+range(10,100,2)+range(100,110)) 1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.sample(a, 3) 1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # A followup to bug #1460340: sampling from a dict could return 1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # a subset of its keys or of its values, depending on the size of 1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the subset requested. 1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao N = 30 1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = dict((i, complex(i, i)) for i in xrange(N)) 1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for k in xrange(N+1): 1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao samp = self.gen.sample(d, k) 1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify that we got ints back (keys); the values are complex. 1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for x in samp: 1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(type(x) is int) 1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao samp.sort() 1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(samp, range(N)) 1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_gauss(self): 1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure that the seed() method initializes all the hidden state. In 1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # particular, through 2.2.1 it failed to reset a piece of state used 1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # by (and only by) the .gauss() method. 1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for seed in 1, 12, 123, 1234, 12345, 123456, 654321: 1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed(seed) 1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x1 = self.gen.random() 1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao y1 = self.gen.gauss(0, 1) 1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed(seed) 1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x2 = self.gen.random() 1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao y2 = self.gen.gauss(0, 1) 1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(x1, x2) 1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(y1, y2) 1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling(self): 1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao state = pickle.dumps(self.gen) 1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao origseq = [self.gen.random() for i in xrange(10)] 1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newgen = pickle.loads(state) 1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao restoredseq = [newgen.random() for i in xrange(10)] 1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(origseq, restoredseq) 1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bug_1727780(self): 1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # verify that version-2-pickles can be loaded 1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # fine, whether they are created on 32-bit or 64-bit 1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # platforms, and that version-3-pickles load fine. 1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao files = [("randv2_32.pck", 780), 1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("randv2_64.pck", 866), 1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("randv3.pck", 343)] 1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for file, value in files: 1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f = open(test_support.findfile(file),"rb") 1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = pickle.load(f) 1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f.close() 1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(r.randrange(1000), value) 1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass WichmannHill_TestBasicOps(TestBasicOps): 1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao gen = random.WichmannHill() 1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_setstate_first_arg(self): 1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.gen.setstate, (2, None, None)) 1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_strong_jumpahead(self): 1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # tests that jumpahead(n) semantics correspond to n calls to random() 1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao N = 1000 1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = self.gen.getstate() 1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.jumpahead(N) 1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r1 = self.gen.random() 1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # now do it the slow way 1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.setstate(s) 1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(N): 1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.random() 1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r2 = self.gen.random() 1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(r1, r2) 1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_gauss_with_whseed(self): 1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure that the seed() method initializes all the hidden state. In 1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # particular, through 2.2.1 it failed to reset a piece of state used 1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # by (and only by) the .gauss() method. 1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for seed in 1, 12, 123, 1234, 12345, 123456, 654321: 1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.whseed(seed) 1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x1 = self.gen.random() 1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao y1 = self.gen.gauss(0, 1) 1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.whseed(seed) 1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x2 = self.gen.random() 1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao y2 = self.gen.gauss(0, 1) 1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(x1, x2) 1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(y1, y2) 1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bigrand(self): 2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify warnings are raised when randrange is too large for random() 2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao with warnings.catch_warnings(): 2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao warnings.filterwarnings("error", "Underlying random") 2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(UserWarning, self.gen.randrange, 2**60) 2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass SystemRandom_TestBasicOps(TestBasicOps): 2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao gen = random.SystemRandom() 2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_autoseed(self): 2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Doesn't need to do anything except not fail 2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed() 2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_saverestore(self): 2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(NotImplementedError, self.gen.getstate) 2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(NotImplementedError, self.gen.setstate, None) 2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_seedargs(self): 2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Doesn't need to do anything except not fail 2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed(100) 2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_jumpahead(self): 2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Doesn't need to do anything except not fail 2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.jumpahead(100) 2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_gauss(self): 2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.gauss_next = None 2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed(100) 2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(self.gen.gauss_next, None) 2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling(self): 2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(NotImplementedError, pickle.dumps, self.gen) 2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_53_bits_per_float(self): 2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This should pass whenever a C double has 53 bit precision. 2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao span = 2 ** 53 2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum = 0 2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(100): 2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum |= int(self.gen.random() * span) 2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cum, span-1) 2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bigrand(self): 2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # The randrange routine should build-up the required number of bits 2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # in stages so that all bit positions are active. 2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao span = 2 ** 500 2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum = 0 2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(100): 2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = self.gen.randrange(span) 2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(0 <= r < span) 2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum |= r 2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cum, span-1) 2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bigrand_ranges(self): 2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in [40,80, 160, 200, 211, 250, 375, 512, 550]: 2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao start = self.gen.randrange(2 ** i) 2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao stop = self.gen.randrange(2 ** (i-2)) 2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if stop <= start: 2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return 2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(start <= self.gen.randrange(start, stop) < stop) 2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_rangelimits(self): 2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]: 2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(set(range(start,stop)), 2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao set([self.gen.randrange(start,stop) for i in xrange(100)])) 2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_genrandbits(self): 2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify ranges 2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for k in xrange(1, 1000): 2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k) 2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify all bits active 2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao getbits = self.gen.getrandbits 2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]: 2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum = 0 2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(100): 2754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum |= getbits(span) 2764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cum, 2**span-1) 2774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify argument checking 2794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.getrandbits) 2804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.getrandbits, 1, 2) 2814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.gen.getrandbits, 0) 2824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.gen.getrandbits, -1) 2834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.getrandbits, 10.1) 2844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_randbelow_logic(self, _log=log, int=int): 2864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check bitcount transition points: 2**i and 2**(i+1)-1 2874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # show that: k = int(1.001 + _log(n, 2)) 2884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # is equal to or one greater than the number of bits in n 2894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(1, 1000): 2904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n = 1L << i # check an exact power of two 2914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao numbits = i+1 2924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao k = int(1.00001 + _log(n, 2)) 2934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(k, numbits) 2944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(n == 2**(k-1)) 2954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n += n - 1 # check 1 below the next power of two 2974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao k = int(1.00001 + _log(n, 2)) 2984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIn(k, [numbits, numbits+1]) 2994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(2**k > n > 2**(k-2)) 3004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n -= n >> 15 # check a little farther below the next power of two 3024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao k = int(1.00001 + _log(n, 2)) 3034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(k, numbits) # note the stronger assertion 3044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(2**k > n > 2**(k-1)) # note the stronger assertion 3054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MersenneTwister_TestBasicOps(TestBasicOps): 3084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao gen = random.Random() 3094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_setstate_first_arg(self): 3114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.gen.setstate, (1, None, None)) 3124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_setstate_middle_arg(self): 3144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Wrong type, s/b tuple 3154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.setstate, (2, None, None)) 3164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Wrong length, s/b 625 3174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.gen.setstate, (2, (1,2,3), None)) 3184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Wrong type, s/b tuple of 625 ints 3194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.setstate, (2, ('a',)*625, None)) 3204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Last element s/b an int also 3214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.setstate, (2, (0,)*624+('a',), None)) 3224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_referenceImplementation(self): 3244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Compare the python implementation with results from the original 3254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # code. Create 2000 53-bit precision random floats. Compare only 3264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the last ten entries to show that the independent implementations 3274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # are tracking. Here is the main() function needed to create the 3284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # list of expected random numbers: 3294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # void main(void){ 3304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # int i; 3314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # unsigned long init[4]={61731, 24903, 614, 42143}, length=4; 3324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # init_by_array(init, length); 3334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # for (i=0; i<2000; i++) { 3344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # printf("%.15f ", genrand_res53()); 3354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # if (i%5==4) printf("\n"); 3364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # } 3374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # } 3384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = [0.45839803073713259, 3394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.86057815201978782, 3404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.92848331726782152, 3414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.35932681119782461, 3424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.081823493762449573, 3434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.14332226470169329, 3444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.084297823823520024, 3454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.53814864671831453, 3464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.089215024911993401, 3474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.78486196105372907] 3484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96)) 3504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao actual = self.randomlist(2000)[-10:] 3514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for a, e in zip(actual, expected): 3524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertAlmostEqual(a,e,places=14) 3534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_strong_reference_implementation(self): 3554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Like test_referenceImplementation, but checks for exact bit-level 3564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # equality. This should pass on any box where C double contains 3574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # at least 53 bits of precision (the underlying algorithm suffers 3584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # no rounding errors -- all results are exact). 3594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from math import ldexp 3604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = [0x0eab3258d2231fL, 3624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0x1b89db315277a5L, 3634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0x1db622a5518016L, 3644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0x0b7f9af0d575bfL, 3654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0x029e4c4db82240L, 3664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0x04961892f5d673L, 3674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0x02b291598e4589L, 3684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0x11388382c15694L, 3694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0x02dad977c9e1feL, 3704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0x191d96d4d334c6L] 3714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96)) 3724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao actual = self.randomlist(2000)[-10:] 3734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for a, e in zip(actual, expected): 3744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(long(ldexp(a, 53)), e) 3754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_long_seed(self): 3774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This is most interesting to run in debug mode, just to make sure 3784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # nothing blows up. Under the covers, a dynamically resized array 3794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # is allocated, consuming space proportional to the number of bits 3804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # in the seed. Unfortunately, that's a quadratic-time algorithm, 3814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # so don't make this horribly big. 3824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao seed = (1L << (10000 * 8)) - 1 # about 10K bytes 3834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed(seed) 3844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_53_bits_per_float(self): 3864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This should pass whenever a C double has 53 bit precision. 3874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao span = 2 ** 53 3884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum = 0 3894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(100): 3904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum |= int(self.gen.random() * span) 3914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cum, span-1) 3924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bigrand(self): 3944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # The randrange routine should build-up the required number of bits 3954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # in stages so that all bit positions are active. 3964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao span = 2 ** 500 3974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum = 0 3984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(100): 3994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao r = self.gen.randrange(span) 4004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(0 <= r < span) 4014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum |= r 4024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cum, span-1) 4034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bigrand_ranges(self): 4054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in [40,80, 160, 200, 211, 250, 375, 512, 550]: 4064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao start = self.gen.randrange(2 ** i) 4074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao stop = self.gen.randrange(2 ** (i-2)) 4084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if stop <= start: 4094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return 4104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(start <= self.gen.randrange(start, stop) < stop) 4114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_rangelimits(self): 4134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]: 4144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(set(range(start,stop)), 4154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao set([self.gen.randrange(start,stop) for i in xrange(100)])) 4164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_genrandbits(self): 4184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify cross-platform repeatability 4194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.gen.seed(1234567) 4204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(self.gen.getrandbits(100), 4214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 97904845777343510404718956115L) 4224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify ranges 4234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for k in xrange(1, 1000): 4244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k) 4254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify all bits active 4274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao getbits = self.gen.getrandbits 4284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]: 4294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum = 0 4304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(100): 4314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cum |= getbits(span) 4324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cum, 2**span-1) 4334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify argument checking 4354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.getrandbits) 4364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.getrandbits, 'a') 4374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.gen.getrandbits, 1, 2) 4384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.gen.getrandbits, 0) 4394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.gen.getrandbits, -1) 4404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_randbelow_logic(self, _log=log, int=int): 4424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check bitcount transition points: 2**i and 2**(i+1)-1 4434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # show that: k = int(1.001 + _log(n, 2)) 4444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # is equal to or one greater than the number of bits in n 4454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(1, 1000): 4464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n = 1L << i # check an exact power of two 4474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao numbits = i+1 4484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao k = int(1.00001 + _log(n, 2)) 4494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(k, numbits) 4504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(n == 2**(k-1)) 4514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n += n - 1 # check 1 below the next power of two 4534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao k = int(1.00001 + _log(n, 2)) 4544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIn(k, [numbits, numbits+1]) 4554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(2**k > n > 2**(k-2)) 4564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n -= n >> 15 # check a little farther below the next power of two 4584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao k = int(1.00001 + _log(n, 2)) 4594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(k, numbits) # note the stronger assertion 4604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(2**k > n > 2**(k-1)) # note the stronger assertion 4614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_randrange_bug_1590891(self): 4634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao start = 1000000000000 4644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao stop = -100000000000000000000 4654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao step = -200 4664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x = self.gen.randrange(start, stop, step) 4674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(stop < x <= start) 4684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((x+stop)%step, 0) 4694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef gamma(z, sqrt2pi=(2.0*pi)**0.5): 4714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Reflection to right half of complex plane 4724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if z < 0.5: 4734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return pi / sin(pi*z) / gamma(1.0-z) 4744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Lanczos approximation with g=7 4754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao az = z + (7.0 - 0.5) 4764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return az ** (z-0.5) / exp(az) * sqrt2pi * fsum([ 4774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.9999999999995183, 4784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 676.5203681218835 / z, 4794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao -1259.139216722289 / (z+1.0), 4804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 771.3234287757674 / (z+2.0), 4814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao -176.6150291498386 / (z+3.0), 4824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12.50734324009056 / (z+4.0), 4834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao -0.1385710331296526 / (z+5.0), 4844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.9934937113930748e-05 / (z+6.0), 4854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0.1659470187408462e-06 / (z+7.0), 4864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ]) 4874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestDistributions(unittest.TestCase): 4894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_zeroinputs(self): 4904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify that distributions can handle a series of zero inputs' 4914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g = random.Random() 4924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x = [g.random() for i in xrange(50)] + [0.0]*5 4934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.uniform(1,10) 4944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.paretovariate(1.0) 4954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.expovariate(1.0) 4964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.weibullvariate(1.0, 1.0) 4974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.vonmisesvariate(1.0, 1.0) 4984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.normalvariate(0.0, 1.0) 4994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.gauss(0.0, 1.0) 5004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.lognormvariate(0.0, 1.0) 5014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.vonmisesvariate(0.0, 1.0) 5024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.gammavariate(0.01, 1.0) 5034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.gammavariate(1.0, 1.0) 5044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.gammavariate(200.0, 1.0) 5054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.betavariate(3.0, 3.0) 5064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop; g.triangular(0.0, 1.0, 1.0/3.0) 5074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_avg_std(self): 5094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Use integration to test distribution average and standard deviation. 5104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Only works for distributions which do not consume variates in pairs 5114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g = random.Random() 5124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao N = 5000 5134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x = [i/float(N) for i in xrange(1,N)] 5144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for variate, args, mu, sigmasqrd in [ 5154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)**2/12), 5164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.triangular, (0.0, 1.0, 1.0/3.0), 4.0/9.0, 7.0/9.0/18.0), 5174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.expovariate, (1.5,), 1/1.5, 1/1.5**2), 5184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.vonmisesvariate, (1.23, 0), pi, pi**2/3), 5194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.paretovariate, (5.0,), 5.0/(5.0-1), 5204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5.0/((5.0-1)**2*(5.0-2))), 5214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.weibullvariate, (1.0, 3.0), gamma(1+1/3.0), 5224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao gamma(1+2/3.0)-gamma(1+1/3.0)**2) ]: 5234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g.random = x[:].pop 5244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao y = [] 5254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(len(x)): 5264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 5274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao y.append(variate(*args)) 5284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except IndexError: 5294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 5304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s1 = s2 = 0 5314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for e in y: 5324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s1 += e 5334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s2 += (e - mu) ** 2 5344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao N = len(y) 5354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertAlmostEqual(s1/N, mu, places=2, 5364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao msg='%s%r' % (variate.__name__, args)) 5374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertAlmostEqual(s2/(N-1), sigmasqrd, places=2, 5384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao msg='%s%r' % (variate.__name__, args)) 5394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_constant(self): 5414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g = random.Random() 5424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao N = 100 5434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for variate, args, expected in [ 5444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.uniform, (10.0, 10.0), 10.0), 5454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.triangular, (10.0, 10.0), 10.0), 5464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #(g.triangular, (10.0, 10.0, 10.0), 10.0), 5474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.expovariate, (float('inf'),), 0.0), 5484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.vonmisesvariate, (3.0, float('inf')), 3.0), 5494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.gauss, (10.0, 0.0), 10.0), 5504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.lognormvariate, (0.0, 0.0), 1.0), 5514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.lognormvariate, (-float('inf'), 0.0), 0.0), 5524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.normalvariate, (10.0, 0.0), 10.0), 5534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.paretovariate, (float('inf'),), 1.0), 5544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.weibullvariate, (10.0, float('inf')), 10.0), 5554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (g.weibullvariate, (0.0, 10.0), 0.0), 5564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ]: 5574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in range(N): 5584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(variate(*args), expected) 5594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_von_mises_range(self): 5614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Issue 17149: von mises variates were not consistently in the 5624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # range [0, 2*PI]. 5634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao g = random.Random() 5644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao N = 100 5654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for mu in 0.0, 0.1, 3.1, 6.2: 5664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for kappa in 0.0, 2.3, 500.0: 5674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for _ in range(N): 5684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sample = g.vonmisesvariate(mu, kappa) 5694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue( 5704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 0 <= sample <= random.TWOPI, 5714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao msg=("vonmisesvariate({}, {}) produced a result {} out" 5724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao " of range [0, 2*pi]").format(mu, kappa, sample)) 5734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_von_mises_large_kappa(self): 5754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Issue #17141: vonmisesvariate() was hang for large kappas 5764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao random.vonmisesvariate(0, 1e15) 5774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao random.vonmisesvariate(0, 1e100) 5784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestModule(unittest.TestCase): 5814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def testMagicConstants(self): 5824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141) 5834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertAlmostEqual(random.TWOPI, 6.28318530718) 5844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertAlmostEqual(random.LOG4, 1.38629436111989) 5854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertAlmostEqual(random.SG_MAGICCONST, 2.50407739677627) 5864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test__all__(self): 5884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # tests validity but not completeness of the __all__ list 5894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(set(random.__all__) <= set(dir(random))) 5904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_random_subclass_with_kwargs(self): 5924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # SF bug #1486663 -- this used to erroneously raise a TypeError 5934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class Subclass(random.Random): 5944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, newarg=None): 5954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao random.Random.__init__(self) 5964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Subclass(newarg=1) 5974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_main(verbose=None): 6004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao testclasses = [WichmannHill_TestBasicOps, 6014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao MersenneTwister_TestBasicOps, 6024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao TestDistributions, 6034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao TestModule] 6044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 6064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao random.SystemRandom().random() 6074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except NotImplementedError: 6084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 6094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 6104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao testclasses.append(SystemRandom_TestBasicOps) 6114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_support.run_unittest(*testclasses) 6134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # verify reference counting 6154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import sys 6164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if verbose and hasattr(sys, "gettotalrefcount"): 6174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao counts = [None] * 5 6184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in xrange(len(counts)): 6194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_support.run_unittest(*testclasses) 6204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao counts[i] = sys.gettotalrefcount() 6214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao print counts 6224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == "__main__": 6244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_main(verbose=True) 625