whrandom.py :  » Mobile » Python-for-PalmOS » Python-1.5.2+reduced-1.0 » Lib » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Mobile » Python for PalmOS 
Python for PalmOS » Python 1.5.2 reduced 1.0 » Lib » whrandom.py
"""Wichman-Hill random number generator.

Wichmann, B. A. & Hill, I. D. (1982)
Algorithm AS 183: 
An efficient and portable pseudo-random number generator
Applied Statistics 31 (1982) 188-190

see also: 
        Correction to Algorithm AS 183
        Applied Statistics 33 (1984) 123  

        McLeod, A. I. (1985)
        A remark on Algorithm AS 183 
        Applied Statistics 34 (1985),198-200


USE:
whrandom.random()       yields double precision random numbers 
                        uniformly distributed between 0 and 1.

whrandom.seed(x, y, z)  must be called before whrandom.random()
                        to seed the generator

There is also an interface to create multiple independent
random generators, and to choose from other ranges.



Multi-threading note: the random number generator used here is not
thread-safe; it is possible that nearly simultaneous calls in
different theads return the same random value.  To avoid this, you
have to use a lock around all calls.  (I didn't want to slow this
down in the serial case by using a lock here.)
"""

# Translated by Guido van Rossum from C source provided by
# Adrian Baddeley.


class whrandom:
  def __init__(self, x = 0, y = 0, z = 0):
    """Initialize an instance.
    Without arguments, initialize from current time.
    With arguments (x, y, z), initialize from them."""
    self.seed(x, y, z)

  def seed(self, x = 0, y = 0, z = 0):
    """Set the seed from (x, y, z).
    These must be integers in the range [0, 256)."""
    if not type(x) == type(y) == type(z) == type(0):
      raise TypeError, 'seeds must be integers'
    if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
      raise ValueError, 'seeds must be in range(0, 256)'
    if 0 == x == y == z:
      # Initialize from current time
      import time
      t = long(time.time() * 256)
      t = int((t&0xffffff) ^ (t>>24))
      t, x = divmod(t, 256)
      t, y = divmod(t, 256)
      t, z = divmod(t, 256)
    # Zero is a poor seed, so substitute 1
    self._seed = (x or 1, y or 1, z or 1)

  def random(self):
    """Get the next random number in the range [0.0, 1.0)."""
    # This part is thread-unsafe:
    # BEGIN CRITICAL SECTION
    x, y, z = self._seed
    #
    x = (171 * x) % 30269
    y = (172 * y) % 30307
    z = (170 * z) % 30323
    #
    self._seed = x, y, z
    # END CRITICAL SECTION
    #
    return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0

  def uniform(self, a, b):
    """Get a random number in the range [a, b)."""
    return a + (b-a) * self.random()

  def randint(self, a, b):
    """Get a random integer in the range [a, b] including both end points.
    (Deprecated; use randrange below.)"""
    return self.randrange(a, b+1)

  def choice(self, seq):
    """Choose a random element from a non-empty sequence."""
    return seq[int(self.random() * len(seq))]

  def randrange(self, start, stop=None, step=1, int=int, default=None):
    """Choose a random item from range([start,] step[, stop]).
    This fixes the problem with randint() which includes the
    endpoint; in Python this is usually not what you want.
      Do not supply the 'int' and 'default' arguments."""
    # This code is a bit messy to make it fast for the
    # common case while still doing adequate error checking
    istart = int(start)
    if istart != start:
      raise ValueError, "non-integer arg 1 for randrange()"
    if stop is default:
      if istart > 0:
        return int(self.random() * istart)
      raise ValueError, "empty range for randrange()"
    istop = int(stop)
    if istop != stop:
      raise ValueError, "non-integer stop for randrange()"
    if step == 1:
      if istart < istop:
        return istart + int(self.random() *
               (istop - istart))
      raise ValueError, "empty range for randrange()"
    istep = int(step)
    if istep != step:
      raise ValueError, "non-integer step for randrange()"
    if istep > 0:
      n = (istop - istart + istep - 1) / istep
    elif istep < 0:
      n = (istop - istart + istep + 1) / istep
    else:
      raise ValueError, "zero step for randrange()"

    if n <= 0:
      raise ValueError, "empty range for randrange()"
    return istart + istep*int(self.random() * n)


# Initialize from the current time
_inst = whrandom()
seed = _inst.seed
random = _inst.random
uniform = _inst.uniform
randint = _inst.randint
choice = _inst.choice
randrange = _inst.randrange
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.