Random Numbers with Python API - Utilities

Skip to content
Back to top
View this page
Edit this page

# Random Numbers with Python API

AUTHORS:

  – Carl Witty (2008-03): new file

This module has the same functions as the Python standard module module{random}, but uses the current sage random number state from module{sage.misc.randstate} (so that it can be controlled by the same global random number seeds).

The functions here are less efficient than the functions in module{random}, because they look up the current random number state on each call.

If you are going to be creating many random numbers in a row, it is better to use the functions in module{sage.misc.randstate} directly.

Here is an example:

(The imports on the next two lines are not necessary, since function{randrange} and function{current_randstate} are both available by default at the code{sage:} prompt; but you would need them to run these examples inside a module.)

Sage

    sage: from sage.misc.prandom import randrange
    sage: from sage.misc.randstate import current_randstate
    sage: def test1():
    ....:    return sum([randrange(100) for i in range(100)])
    sage: def test2():
    ....:    randrange = current_randstate().python_random().randrange
    ....:    return sum([randrange(100) for i in range(100)])

Python

    >>> from sage.all import *
    >>> from sage.misc.prandom import randrange
    >>> from sage.misc.randstate import current_randstate
    >>> def test1():
    ...    return sum([randrange(Integer(100)) for i in range(Integer(100))])
    >>> def test2():
    ...    randrange = current_randstate().python_random().randrange
    ...    return sum([randrange(Integer(100)) for i in range(Integer(100))])

Test2 will be slightly faster than test1, but they give the same answer:

Sage

    sage: with seed(0): test1()
    5169
    sage: with seed(0): test2()
    5169
    sage: with seed(1): test1()
    5097
    sage: with seed(1): test2()
    5097
    sage: timeit('test1()') # random
    625 loops, best of 3: 590 us per loop
    sage: timeit('test2()') # random
    625 loops, best of 3: 460 us per loop

[Python]

    >>> from sage.all import *
    >>> with seed(Integer(0)): test1()
    5169
    >>> with seed(Integer(0)): test2()
    5169
    >>> with seed(Integer(1)): test1()
    5097
    >>> with seed(Integer(1)): test2()
    5097
    >>> timeit('test1()') # random
    625 loops, best of 3: 590 us per loop
    >>> timeit('test2()') # random
    625 loops, best of 3: 460 us per loop

The docstrings for the functions in this file are mostly copied from Python’s file{random.py}, so those docstrings are “Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation; All Rights Reserved” and are available under the terms of the Python Software Foundation License Version 2.

sage.misc.prandom.betavariate(alpha, beta)

  Beta distribution.

  Conditions on the parameters are alpha > 0 and beta > 0. Returned values range between 0 and 1.

  EXAMPLES:

  Sage

      sage: s = betavariate(0.1, 0.9); s  # random
      9.75087916621299e-9
      sage: 0.0 <= s <= 1.0
      True

      sage: s = betavariate(0.9, 0.1); s  # random
      0.941890400939253
      sage: 0.0 <= s <= 1.0
      True

  Python

      >>> from sage.all import *
      >>> s = betavariate(RealNumber('0.1'), RealNumber('0.9')); s  # random
      9.75087916621299e-9
      >>> RealNumber('0.0') <= s <= RealNumber('1.0')
      True

      >>> s = betavariate(RealNumber('0.9'), RealNumber('0.1')); s  # random
      0.941890400939253
      >>> RealNumber('0.0') <= s <= RealNumber('1.0')
      True

sage.misc.prandom.choice(seq)

  Choose a random element from a non-empty sequence.

  EXAMPLES:

  Sage

      sage: s = [choice(list(primes(10, 100))) for i in range(5)]; s  # random        # needs sage.libs.pari
      [17, 47, 11, 31, 47]
      sage: all(t in primes(10, 100) for t in s)                                      # needs sage.libs.pari
      True

  Python

      >>> from sage.all import *
      >>> s = [choice(list(primes(Integer(10), Integer(100)))) for i in range(Integer(5))]; s  # random        # needs sage.libs.pari
      [17, 47, 11, 31, 47]
      >>> all(t in primes(Integer(10), Integer(100)) for t in s)                                      # needs sage.libs.pari
      True

sage.misc.prandom.expovariate(lambd)

  Exponential distribution.

  lambd is 1.0 divided by the desired mean. (The parameter would be called “lambda”, but that is a reserved word in Python.) Returned values range from 0 to positive infinity.

  EXAMPLES:

  Sage

      sage: sample = [expovariate(0.001) for i in range(3)]; sample  # random
      [118.152309288166, 722.261959038118, 45.7190543690470]
      sage: all(s >= 0.0 for s in sample)
      True

      sage: sample = [expovariate(1.0) for i in range(3)]; sample  # random
      [0.404201816061304, 0.735220464997051, 0.201765578600627]
      sage: all(s >= 0.0 for s in sample)
      True

      sage: sample = [expovariate(1000) for i in range(3)]; sample  # random
      [0.0012068700332283973, 8.340929747302108e-05, 0.00219877067980605]
      sage: all(s >= 0.0 for s in sample)
      True

  Python

      >>> from sage.all import *
      >>> sample = [expovariate(RealNumber('0.001')) for i in range(Integer(3))]; sample  # random
      [118.152309288166, 722.261959038118, 45.7190543690470]
      >>> all(s >= RealNumber('0.0') for s in sample)
      True

      >>> sample = [expovariate(RealNumber('1.0')) for i in range(Integer(3))]; sample  # random
      [0.404201816061304, 0.735220464997051, 0.201765578600627]
      >>> all(s >= RealNumber('0.0') for s in sample)
      True

      >>> sample = [expovariate(Integer(1000)) for i in range(Integer(3))]; sample  # random
      [0.0012068700332283973, 8.340929747302108e-05, 0.00219877067980605]
      >>> all(s >= RealNumber('0.0') for s in sample)
      True

sage.misc.prandom.gammavariate(alpha, beta)

  Gamma distribution. (Not the gamma function.)

  Conditions on the parameters are alpha > 0 and beta > 0.

  EXAMPLES:

  Sage

      sage: sample = gammavariate(1.0, 3.0); sample  # random
      6.58282586130638
      sage: sample > 0
      True
      sage: sample = gammavariate(3.0, 1.0); sample  # random
      3.07801512341612
      sage: sample > 0
      True

  Python

      >>> from sage.all import *
      >>> sample = gammavariate(RealNumber('1.0'), RealNumber('3.0')); sample  # random
      6.58282586130638
      >>> sample > Integer(0)
      True
      >>> sample = gammavariate(RealNumber('3.0'), RealNumber('1.0')); sample  # random
      3.07801512341612
      >>> sample > Integer(0)
      True

sage.misc.prandom.gauss(mu, sigma)

  Gaussian distribution.

  mu is the mean, and sigma is the standard deviation. This is slightly faster than the normalvariate() function, but is not thread-safe.

  EXAMPLES:

  Sage

      sage: [gauss(0, 1) for i in range(3)]  # random
      [0.9191011757657915, 0.7744526756246484, 0.8638996866800877]
      sage: [gauss(0, 100) for i in range(3)]  # random
      [24.916051749154448, -62.99272061579273, -8.1993122536718...]
      sage: [gauss(1000, 10) for i in range(3)]  # random
      [998.7590700045661, 996.1087338511692, 1010.1256817458031]

  Python

      >>> from sage.all import *
      >>> [gauss(Integer(0), Integer(1)) for i in range(Integer(3))]  # random
      [0.9191011757657915, 0.7744526756246484, 0.8638996866800877]
      >>> [gauss(Integer(0), Integer(100)) for i in range(Integer(3))]  # random
      [24.916051749154448, -62.99272061579273, -8.1993122536718...]
      >>> [gauss(Integer(1000), Integer(10)) for i in range(Integer(3))]  # random
      [998.7590700045661, 996.1087338511692, 1010.1256817458031]

sage.misc.prandom.getrandbits(k) → x. Generates a long int with k random bits.

  EXAMPLES:

  Sage

      sage: getrandbits(10) in range(2^10)
      True
      sage: getrandbits(200) in range(2^200)
      True
      sage: getrandbits(4) in range(2^4)
      True

  Python

      >>> from sage.all import *
      >>> getrandbits(Integer(10)) in range(Integer(2)**Integer(10))
      True
      >>> getrandbits(Integer(200)) in range(Integer(2)**Integer(200))
      True
      >>> getrandbits(Integer(4)) in range(Integer(2)**Integer(4))
      True

sage.misc.prandom.lognormvariate(mu, sigma)

  Log normal distribution.

  If you take the natural logarithm of this distribution, you’ll get a normal distribution with mean mu and standard deviation sigma. mu can have any value, and sigma must be greater than zero.

  EXAMPLES:

  Sage

      sage: [lognormvariate(100, 10) for i in range(3)]  # random
      [2.9410355688290246e+37, 2.2257548162070125e+38, 4.142299451717446e+43]

  Python

      >>> from sage.all import *
      >>> [lognormvariate(Integer(100), Integer(10)) for i in range(Integer(3))]  # random
      [2.9410355688290246e+37, 2.2257548162070125e+38, 4.142299451717446e+43]

sage.misc.prandom.normalvariate(mu, sigma)

  Normal distribution.

  mu is the mean, and sigma is the standard deviation.

  EXAMPLES:

  Sage

      sage: [normalvariate(0, 1) for i in range(3)]  # random
      [-1.372558980559407, -1.1701670364898928, 0.04324100555110143]
      sage: [normalvariate(0, 100) for i in range(3)]  # random
      [37.45695875041769, 159.6347743233298, 124.1029321124009]
      sage: [normalvariate(1000, 10) for i in range(3)]  # random
      [1008.5303090383741, 989.8624892644895, 985.7728921150242]

  Python

      >>> from sage.all import *
      >>> [normalvariate(Integer(0), Integer(1)) for i in range(Integer(3))]  # random
      [-1.372558980559407, -1.1701670364898928, 0.04324100555110143]
      >>> [normalvariate(Integer(0), Integer(100)) for i in range(Integer(3))]  # random
      [37.45695875041769, 159.6347743233298, 124.1029321124009]
      >>> [normalvariate(Integer(1000), Integer(10)) for i in range(Integer(3))]  # random
      [1008.5303090383741, 989.8624892644895, 985.7728921150242]

sage.misc.prandom.paretovariate(alpha)

  Pareto distribution. alpha is the shape parameter.

  EXAMPLES:

  Sage

      sage: sample = [paretovariate(3) for i in range(1, 5)]; sample  # random
      [1.0401699394233033, 1.2722080162636495, 1.0153564009379579, 1.1442323078983077]
      sage: all(s >= 1.0 for s in sample)
      True

  Python

      >>> from sage.all import *
      >>> sample = [paretovariate(Integer(3)) for i in range(Integer(1), Integer(5))]; sample  # random
      [1.0401699394233033, 1.2722080162636495, 1.0153564009379579, 1.1442323078983077]
      >>> all(s >= RealNumber('1.0') for s in sample)
      True

sage.misc.prandom.randint(a, b)

  Return random integer in range [a, b], including both end points.

  EXAMPLES:

  Sage

      sage: s = [randint(0, 2) for i in range(15)]; s  # random
      [0, 1, 0, 0, 1, 0, 2, 0, 2, 1, 2, 2, 0, 2, 2]
      sage: all(t in [0, 1, 2] for t in s)
      True
      sage: -100 <= randint(-100, 10) <= 10
      True

  Python

      >>> from sage.all import *
      >>> s = [randint(Integer(0), Integer(2)) for i in range(Integer(15))]; s  # random
      [0, 1, 0, 0, 1, 0, 2, 0, 2, 1, 2, 2, 0, 2, 2]
      >>> all(t in [Integer(0), Integer(1), Integer(2)] for t in s)
      True
      >>> -Integer(100) <= randint(-Integer(100), Integer(10)) <= Integer(10)
      True

sage.misc.prandom.random()

  Get the next random number in the range [0.0, 1.0).

  EXAMPLES:

  Sage

      sage: sample = [random() for i in [1 .. 4]]; sample  # random
      [0.111439293741037, 0.5143475134191677, 0.04468968524815642, 0.332490606442413]
      sage: all(0.0 <= s <= 1.0 for s in sample)
      True

  Python

      >>> from sage.all import *
      >>> sample = [random() for i in (ellipsis_range(Integer(1) ,Ellipsis, Integer(4)))]; sample  # random
      [0.111439293741037, 0.5143475134191677, 0.04468968524815642, 0.332490606442413]
      >>> all(RealNumber('0.0') <= s <= RealNumber('1.0') for s in sample)
      True

sage.misc.prandom.randrange(start, stop=None, step=1)

  Choose a random item from range(start, stop[, step]).

  This fixes the problem with randint() which includes the endpoint; in Python this is usually not what you want.

  EXAMPLES:

  Sage

      sage: s = randrange(0, 100, 11)
      sage: 0 <= s < 100
      True
      sage: s % 11
      0

      sage: 5000 <= randrange(5000, 5100) < 5100
      True
      sage: s = [randrange(0, 2) for i in range(15)]
      sage: all(t in [0, 1] for t in s)
      True

      sage: s = randrange(0, 1000000, 1000)
      sage: 0 <= s < 1000000
      True
      sage: s % 1000
      0
      sage: -100 <= randrange(-100, 10) < 10
      True

  Python

      >>> from sage.all import *
      >>> s = randrange(Integer(0), Integer(100), Integer(11))
      >>> Integer(0) <= s < Integer(100)
      True
      >>> s % Integer(11)
      0

      >>> Integer(5000) <= randrange(Integer(5000), Integer(5100)) < Integer(5100)
      True
      >>> s = [randrange(Integer(0), Integer(2)) for i in range(Integer(15))]
      >>> all(t in [Integer(0), Integer(1)] for t in s)
      True

      >>> s = randrange(Integer(0), Integer(1000000), Integer(1000))
      >>> Integer(0) <= s < Integer(1000000)
      True
      >>> s % Integer(1000)
      0
      >>> -Integer(100) <= randrange(-Integer(100), Integer(10)) < Integer(10)
      True

sage.misc.prandom.sample(population, k)

  Choose k unique random elements from a population sequence.

  Return a new list containing elements from the population while leaving the original population unchanged. The resulting list is in selection order so that all sub-slices will also be valid random samples. This allows raffle winners (the sample) to be partitioned into grand prize and second place winners (the subslices).

  Members of the population need not be hashable or unique. If the population contains repeats, then each occurrence is a possible selection in the sample.

  To choose a sample in a range of integers, use xrange as an argument (in Python 2) or range (in Python 3). This is especially fast and space efficient for sampling from a large population: sample(range(10000000), 60)

  EXAMPLES:

  Sage

      sage: from sage.misc.misc import is_sublist
      sage: l = ["Here", "I", "come", "to", "save", "the", "day"]
      sage: s = sample(l, 3); s  # random
      ['Here', 'to', 'day']
      sage: is_sublist(sorted(s), sorted(l))
      True
      sage: len(s)
      3

      sage: s = sample(range(2^30), 7); s  # random
      [357009070, 558990255, 196187132, 752551188, 85926697, 954621491, 624802848]
      sage: len(s)
      7
      sage: all(t in range(2^30) for t in s)
      True

  Python

      >>> from sage.all import *
      >>> from sage.misc.misc import is_sublist
      >>> l = ["Here", "I", "come", "to", "save", "the", "day"]
      >>> s = sample(l, Integer(3)); s  # random
      ['Here', 'to', 'day']
      >>> is_sublist(sorted(s), sorted(l))
      True
      >>> len(s)
      3

      >>> s = sample(range(Integer(2)**Integer(30)), Integer(7)); s  # random
      [357009070, 558990255, 196187132, 752551188, 85926697, 954621491, 624802848]
      >>> len(s)
      7
      >>> all(t in range(Integer(2)**Integer(30)) for t in s)
      True

sage.misc.prandom.shuffle(x)

  x, random=random.random -> shuffle list x in place; return None.

  Optional arg random is a 0-argument function returning a random float in [0.0, 1.0); by default, the sage.misc.random.random.

  EXAMPLES:

  Sage

      sage: shuffle([1 .. 10])

  Python

      >>> from sage.all import *
      >>> shuffle((ellipsis_range(Integer(1) ,Ellipsis, Integer(10))))

sage.misc.prandom.uniform(a, b)

  Get a random number in the range [a, b).

  Equivalent to code{a + (b-a) * random()}.

  EXAMPLES:

  Sage

      sage: s = uniform(0, 1); s  # random
      0.111439293741037
      sage: 0.0 <= s <= 1.0
      True

      sage: s = uniform(e, pi); s  # random                                           # needs sage.symbolic
      0.5143475134191677*pi + 0.48565248658083227*e
      sage: bool(e <= s <= pi)                                                        # needs sage.symbolic
      True

  Python

      >>> from sage.all import *
      >>> s = uniform(Integer(0), Integer(1)); s  # random
      0.111439293741037
      >>> RealNumber('0.0') <= s <= RealNumber('1.0')
      True

      >>> s = uniform(e, pi); s  # random                                           # needs sage.symbolic
      0.5143475134191677*pi + 0.48565248658083227*e
      >>> bool(e <= s <= pi)                                                        # needs sage.symbolic
      True

sage.misc.prandom.vonmisesvariate(mu, kappa)

  Circular data distribution.

  mu is the mean angle, expressed in radians between 0 and 2*pi, and kappa is the concentration parameter, which must be greater than or equal to zero. If kappa is equal to zero, this distribution reduces to a uniform random angle over the range 0 to 2*pi.

  EXAMPLES:

  Sage

      sage: sample = [vonmisesvariate(1.0r, 3.0r) for i in range(1, 5)]; sample  # random
      [0.898328639355427, 0.6718030007041281, 2.0308777524813393, 1.714325253725145]
      sage: all(s >= 0.0 for s in sample)
      True

  Python

      >>> from sage.all import *
      >>> sample = [vonmisesvariate(1.0, 3.0) for i in range(Integer(1), Integer(5))]; sample  # random
      [0.898328639355427, 0.6718030007041281, 2.0308777524813393, 1.714325253725145]
      >>> all(s >= RealNumber('0.0') for s in sample)
      True

sage.misc.prandom.weibullvariate(alpha, beta)

  Weibull distribution.

  alpha is the scale parameter and beta is the shape parameter.

  EXAMPLES:

  Sage

      sage: sample = [weibullvariate(1, 3) for i in range(1, 5)]; sample  # random
      [0.49069775546342537, 0.8972185564611213, 0.357573846531942, 0.739377255516847]
      sage: all(s >= 0.0 for s in sample)
      True

  Python

      >>> from sage.all import *
      >>> sample = [weibullvariate(Integer(1), Integer(3)) for i in range(Integer(1), Integer(5))]; sample  # random
      [0.49069775546342537, 0.8972185564611213, 0.357573846531942, 0.739377255516847]
      >>> all(s >= RealNumber('0.0') for s in sample)
      True