Changeset 388 for python/vendor/current/Lib/random.py
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Lib/random.py
r2 r388 47 47 from os import urandom as _urandom 48 48 from binascii import hexlify as _hexlify 49 import hashlib as _hashlib 49 50 50 51 __all__ = ["Random","seed","random","uniform","randint","choice","sample", … … 142 143 (version, self.VERSION)) 143 144 145 def jumpahead(self, n): 146 """Change the internal state to one that is likely far away 147 from the current state. This method will not be in Py3.x, 148 so it is better to simply reseed. 149 """ 150 # The super.jumpahead() method uses shuffling to change state, 151 # so it needs a large and "interesting" n to work with. Here, 152 # we use hashing to create a large n for the shuffle. 153 s = repr(n) + repr(self.getstate()) 154 n = int(_hashlib.new('sha512', s).hexdigest(), 16) 155 super(Random, self).jumpahead(n) 156 144 157 ## ---- Methods below this point do not need to be overridden when 145 158 ## ---- subclassing for the purpose of using a different core generator. … … 158 171 ## -------------------- integer methods ------------------- 159 172 160 def randrange(self, start, stop=None, step=1, int=int, default=None, 161 maxwidth=1L<<BPF): 173 def randrange(self, start, stop=None, step=1, _int=int, _maxwidth=1L<<BPF): 162 174 """Choose a random item from range(start, stop[, step]). 163 175 164 176 This fixes the problem with randint() which includes the 165 177 endpoint; in Python this is usually not what you want. 166 Do not supply the 'int', 'default', and 'maxwidth' arguments. 178 167 179 """ 168 180 169 181 # This code is a bit messy to make it fast for the 170 182 # common case while still doing adequate error checking. 171 istart = int(start)183 istart = _int(start) 172 184 if istart != start: 173 185 raise ValueError, "non-integer arg 1 for randrange()" 174 if stop is default:186 if stop is None: 175 187 if istart > 0: 176 if istart >= maxwidth:188 if istart >= _maxwidth: 177 189 return self._randbelow(istart) 178 return int(self.random() * istart)190 return _int(self.random() * istart) 179 191 raise ValueError, "empty range for randrange()" 180 192 181 193 # stop argument supplied. 182 istop = int(stop)194 istop = _int(stop) 183 195 if istop != stop: 184 196 raise ValueError, "non-integer stop for randrange()" … … 198 210 # compatibility). 199 211 200 if width >= maxwidth:201 return int(istart + self._randbelow(width))202 return int(istart +int(self.random()*width))212 if width >= _maxwidth: 213 return _int(istart + self._randbelow(width)) 214 return _int(istart + _int(self.random()*width)) 203 215 if step == 1: 204 216 raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width) 205 217 206 218 # Non-unit step argument supplied. 207 istep = int(step)219 istep = _int(step) 208 220 if istep != step: 209 221 raise ValueError, "non-integer step for randrange()" … … 218 230 raise ValueError, "empty range for randrange()" 219 231 220 if n >= maxwidth:232 if n >= _maxwidth: 221 233 return istart + istep*self._randbelow(n) 222 return istart + istep* int(self.random() * n)234 return istart + istep*_int(self.random() * n) 223 235 224 236 def randint(self, a, b): … … 228 240 return self.randrange(a, b+1) 229 241 230 def _randbelow(self, n, _log=_log, int=int, _maxwidth=1L<<BPF,242 def _randbelow(self, n, _log=_log, _int=int, _maxwidth=1L<<BPF, 231 243 _Method=_MethodType, _BuiltinMethod=_BuiltinMethodType): 232 244 """Return a random int in the range [0,n) … … 245 257 # This assures that the two methods correspond. 246 258 if type(self.random) is _BuiltinMethod or type(getrandbits) is _Method: 247 k = int(1.00001 + _log(n-1, 2.0)) # 2**k > n-1 > 2**(k-2)259 k = _int(1.00001 + _log(n-1, 2.0)) # 2**k > n-1 > 2**(k-2) 248 260 r = getrandbits(k) 249 261 while r >= n: … … 253 265 _warn("Underlying random() generator does not supply \n" 254 266 "enough bits to choose from a population range this large") 255 return int(self.random() * n)267 return _int(self.random() * n) 256 268 257 269 ## -------------------- sequence methods ------------------- … … 261 273 return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty 262 274 263 def shuffle(self, x, random=None , int=int):275 def shuffle(self, x, random=None): 264 276 """x, random=random.random -> shuffle list x in place; return None. 265 277 266 278 Optional arg random is a 0-argument function returning a random 267 279 float in [0.0, 1.0); by default, the standard random.random. 280 268 281 """ 269 282 270 283 if random is None: 271 284 random = self.random 285 _int = int 272 286 for i in reversed(xrange(1, len(x))): 273 287 # pick an element in x[:i+1] with which to exchange x[i] 274 j = int(random() * (i+1))288 j = _int(random() * (i+1)) 275 289 x[i], x[j] = x[j], x[i] 276 290 … … 292 306 large population: sample(xrange(10000000), 60) 293 307 """ 294 295 # XXX Although the documentation says `population` is "a sequence",296 # XXX attempts are made to cater to any iterable with a __len__297 # XXX method. This has had mixed success. Examples from both298 # XXX sides: sets work fine, and should become officially supported;299 # XXX dicts are much harder, and have failed in various subtle300 # XXX ways across attempts. Support for mapping types should probably301 # XXX be dropped (and users should pass mapping.keys() or .values()302 # XXX explicitly).303 308 304 309 # Sampling without replacement entails tracking either potential … … 314 319 n = len(population) 315 320 if not 0 <= k <= n: 316 raise ValueError , "sample larger than population"321 raise ValueError("sample larger than population") 317 322 random = self.random 318 323 _int = int … … 424 429 # ('lambda' is a Python reserved word) 425 430 426 random = self.random 427 u = random() 428 while u <= 1e-7: 429 u = random() 430 return -_log(u)/lambd 431 # we use 1-random() instead of random() to preclude the 432 # possibility of taking the log of zero. 433 return -_log(1.0 - self.random())/lambd 431 434 432 435 ## -------------------- von Mises distribution -------------------- … … 456 459 return TWOPI * random() 457 460 458 a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa) 459 b = (a - _sqrt(2.0 * a))/(2.0 * kappa) 460 r = (1.0 + b * b)/(2.0 * b) 461 s = 0.5 / kappa 462 r = s + _sqrt(1.0 + s * s) 461 463 462 464 while 1: 463 465 u1 = random() 464 465 466 z = _cos(_pi * u1) 466 f = (1.0 + r * z)/(r + z) 467 c = kappa * (r - f) 468 467 468 d = z / (r + z) 469 469 u2 = random() 470 471 if u2 < c * (2.0 - c) or u2 <= c * _exp(1.0 - c): 470 if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d): 472 471 break 473 472 473 q = 1.0 / r 474 f = (q + z) / (1.0 + q * z) 474 475 u3 = random() 475 476 if u3 > 0.5: 476 theta = (mu % TWOPI) + _acos(f)477 theta = (mu + _acos(f)) % TWOPI 477 478 else: 478 theta = (mu % TWOPI) - _acos(f)479 theta = (mu - _acos(f)) % TWOPI 479 480 480 481 return theta … … 486 487 487 488 Conditions on the parameters are alpha > 0 and beta > 0. 489 490 The probability distribution function is: 491 492 x ** (alpha - 1) * math.exp(-x / beta) 493 pdf(x) = -------------------------------------- 494 math.gamma(alpha) * beta ** alpha 488 495 489 496 """ … … 589 596 ## -------------------- beta -------------------- 590 597 ## See 591 ## http:// sourceforge.net/bugs/?func=detailbug&bug_id=130030&group_id=5470598 ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html 592 599 ## for Ivan Frohne's insightful analysis of why the original implementation: 593 600 ##
Note:
See TracChangeset
for help on using the changeset viewer.