=============
Simple Random
=============
:Author: Craig McQueen
:Contact: http://craig.mcqueen.id.au/
:Copyright: 2010 Craig McQueen
Simple pseudo-random number generators.
-----
Intro
-----
The ``simplerandom`` package is provided, which contains modules containing
classes for various simple pseudo-random number generators.
One module provides Python iterators, which generate simple unsigned 32-bit
integers identical to their C counterparts.
Another module provides random classes that are sub-classed from the class
``Random`` in the ``random`` module of the standard Python library.
Why use this package? These random number generators are very simple, which
has two main advantages:
* It is easy to port them to a different platform and/or language. It can be
useful to be able to implement the identical algorithm on multiple
platforms and/or languages.
* Small and simple generators can be more appropriate for small embedded
systems, with limited RAM and ROM.
An equivalent C implementation (of the Python ``simplerandom.iterators``
module) has been created. See:
http://github.com/cmcqueen/simplerandom
Algorithms
``````````
Most algorithms were obtained from two newsgroup posts by George Marsaglia
[#marsaglia1999]_ [#marsaglia2003]_. However, some modifications have been
made. From [#rose]_, it seems that the SHR3 algorithm defined in
[#marsaglia1999]_ is flawed and should not be used. It doesn't actually have a
period of 2**32-1 as expected, but has 64 different cycles, some with very
short periods. The SHR3 in the 2003 post is very similar, but with two shift
values swapped. It has a period of 2**32-1 as expected.
We still find KISS from [#marsaglia1999]_ useful mainly because it uses 32-bit
calculations for MWC, which can be more suitable for small embedded systems.
So we define KISS that uses a MWC based on [#marsaglia1999]_, but the Cong and
SHR3 from [#marsaglia2003]_.
From Pierre L'Ecuyer [#lecuyer1999]_ [#lecuyer1996]_, the Combined LFSR
(Tausworthe) LFSR113 algorithm [#lfsr113]_ and LFSR88 (aka Taus88) have been
implemented.
References
``````````
.. [#marsaglia1999] | `Random Numbers for C\: End, at last?`__
| George Marsaglia
| Newsgroup post, sci.stat.math and others, Thu, 21 Jan 1999
.. __:
.. _Random Numbers for C\: End, at last?:
http://www.cse.yorku.ca/~oz/marsaglia-rng.html
.. [#marsaglia2003] | `RNGs`__
| George Marsaglia
| Newsgroup post, sci.math, 26 Feb 2003
.. __:
.. _RNGs:
http://groups.google.com/group/sci.math/msg/9959175f66dd138f
.. [#rose] | `KISS: A Bit Too Simple`__
| Greg Rose
| Qualcomm Inc.
.. __:
.. _KISS\: A Bit Too Simple:
http://eprint.iacr.org/2011/007.pdf
.. [#lecuyer1999] | `Tables of Maximally-Equidistributed Combined LFSR Generators`__
| Pierre L'Ecuyer
| Mathematics of Computation, 68, 225 (1999), 261–269.
.. __:
.. _Tables of Maximally-Equidistributed Combined LFSR Generators:
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.43.3639
.. [#lfsr113] | `LFSR113 C double implementation`__
| Pierre L'Ecuyer
.. __:
.. _LFSR113 C double implementation:
http://www.iro.umontreal.ca/~simardr/rng/lfsr113.c
.. [#lecuyer1996] | `Maximally Equidistributed Combined Tausworthe Generators`__
| P. L'Ecuyer
| Mathematics of Computation, 65, 213 (1996), 203–213.
.. __:
.. _Maximally Equidistributed Combined Tausworthe Generators:
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.43.4155
----------------
Modules Provided
----------------
========================== ===========================================================================
Module Description
========================== ===========================================================================
``simplerandom.iterators`` Iterator classes, which generate unsigned 32-bit integers.
``simplerandom.random`` Classes that conform to standard Python ``random.Random`` API.
========================== ===========================================================================
Random Number Generators Provided
`````````````````````````````````
In ``simplerandom.iterators``, the following pseudo-random number generators are provided:
========================== ===========================================================================
Generator Notes
========================== ===========================================================================
``MWC1`` Two 32-bit MWCs combined. From [#marsaglia1999]_.
``MWC2`` Very similar to ``MWC1``, but slightly modified to improve its statistical properties.
``Cong`` From [#marsaglia2003]_.
``SHR3`` From [#marsaglia2003]_.
``MWC64`` A single 64-bit multiply-with-carry calculation. From [#marsaglia2003]_.
``KISS`` Combination of MWC2, Cong and SHR3. Based on [#marsaglia1999]_ but using Cong and SHR3 from [#marsaglia2003]_, and the modified MWC.
``KISS2`` Combination of MWC64, Cong and SHR3. From [#marsaglia2003]_.
``LFSR113`` Combined LFSR (Tausworthe) random number generator by L'Ecuyer. From [#lecuyer1999]_ [#lfsr113]_.
``LFSR88`` Combined LFSR (Tausworthe) random number generator by L'Ecuyer. From [#lecuyer1996]_.
========================== ===========================================================================
These generators are Python iterators, of infinite length (they never raise
``StopIteration``). They implement the ``__next__()`` function to generate the
next random integer. All the generators output 32-bit unsigned values, and
take one or more 32-bit seed values during initialisation/seeding.
In ``simplerandom.random``, pseudo-random number generators are provided which
have the same names as those in ``simplerandom.iterators``, but these
generators implement the standard Python ``random.Random`` API. Each generator
uses the iterator of the same name in ``simplerandom.iterators`` to generate
the random bits used to produce the random floats. The ``jumpahead()`` function
(in the style of the Python 2.x API) is implemented in all cases, even though
``jumpahead()`` has officially been removed from the Python 3.x ``random`` API.
-----
Usage
-----
Iterators
`````````
>>> import simplerandom.iterators as sri
>>> rng = sri.KISS(123958, 34987243, 3495825239, 2398172431)
>>> next(rng)
702862187
>>> next(rng)
13888114
>>> next(rng)
699722976
Random class API
````````````````
>>> import simplerandom.random as srr
>>> rng = srr.KISS(258725234)
>>> rng.random()
0.0925917826051541
>>> rng.random()
0.02901686453730415
>>> rng.random()
0.9024972981686489
-------------------------
Supported Python Versions
-------------------------
Python >= 3.10 are supported.
Python versions < 3.10 might work, but have not been tested.
-------------
Use of Cython
-------------
`Cython`_ is used to make a fast implementation of ``simplerandom.iterators``.
Cython creates a ``.c`` file that can be compiled into a Python binary
extension module.
The ``simplerandom`` source distribution package includes a ``.c`` file that
was created with Cython, so it is not necessary to have Cython installed to
install ``simplerandom``.
The Cython ``.pyx`` file is also included, if you want to modify the Cython
source code, in which case you do need to have Cython installed. But by
default, ``setup.py`` builds the extension from the ``.c`` file (to ensure
that the build doesn't fail due to particular Cython version issues). If you
wish to build using Cython from the included ``.pyx`` file, you must set
``USE_CYTHON=True`` in ``setup.py``.
.. _Cython:
http://cython.org/
------------
Installation
------------
The simplerandom package is installed using ``distutils``. If you have the tools
installed to build a Python extension module, run the following command::
python setup.py install
If you cannot build the C extension, you may install just the pure Python
implementation, using the following command::
python setup.py build_py install --skip-build
------------
Unit Testing
------------
Unit testing of the iterators is in ``simplerandom.iterators.test``. It
duplicates the tests of the C algorithms given in the original newsgroup post
[#marsaglia1999]_, as well as other unit tests.
To run unit tests::
python -m simplerandom.iterators.test
A more thorough unit test suite is needed. A unit test suite for
``simplerandom.random`` is needed.
-------
License
-------
The code is released under the MIT license. See LICENSE.txt for details.
Raw data
{
"_id": null,
"home_page": null,
"name": "simplerandom",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "simple, random, pseudorandom, RNG, PRNG",
"author": null,
"author_email": "Craig McQueen <craig@mcqueen.au>",
"download_url": "https://files.pythonhosted.org/packages/6e/cc/0ea4b1b7973394523eb0711d4b88fedc7e1bbb00224717e6855e1717a980/simplerandom-0.13.8.tar.gz",
"platform": null,
"description": "=============\r\nSimple Random\r\n=============\r\n\r\n:Author: Craig McQueen\r\n:Contact: http://craig.mcqueen.id.au/\r\n:Copyright: 2010 Craig McQueen\r\n\r\n\r\nSimple pseudo-random number generators.\r\n\r\n-----\r\nIntro\r\n-----\r\n\r\nThe ``simplerandom`` package is provided, which contains modules containing\r\nclasses for various simple pseudo-random number generators.\r\n\r\nOne module provides Python iterators, which generate simple unsigned 32-bit\r\nintegers identical to their C counterparts.\r\n\r\nAnother module provides random classes that are sub-classed from the class\r\n``Random`` in the ``random`` module of the standard Python library.\r\n\r\nWhy use this package? These random number generators are very simple, which\r\nhas two main advantages:\r\n\r\n* It is easy to port them to a different platform and/or language. It can be\r\n useful to be able to implement the identical algorithm on multiple\r\n platforms and/or languages.\r\n* Small and simple generators can be more appropriate for small embedded\r\n systems, with limited RAM and ROM.\r\n\r\nAn equivalent C implementation (of the Python ``simplerandom.iterators``\r\nmodule) has been created. See:\r\n\r\n http://github.com/cmcqueen/simplerandom\r\n\r\nAlgorithms\r\n``````````\r\n\r\nMost algorithms were obtained from two newsgroup posts by George Marsaglia\r\n[#marsaglia1999]_ [#marsaglia2003]_. However, some modifications have been\r\nmade. From [#rose]_, it seems that the SHR3 algorithm defined in\r\n[#marsaglia1999]_ is flawed and should not be used. It doesn't actually have a\r\nperiod of 2**32-1 as expected, but has 64 different cycles, some with very\r\nshort periods. The SHR3 in the 2003 post is very similar, but with two shift\r\nvalues swapped. It has a period of 2**32-1 as expected.\r\n\r\nWe still find KISS from [#marsaglia1999]_ useful mainly because it uses 32-bit\r\ncalculations for MWC, which can be more suitable for small embedded systems.\r\nSo we define KISS that uses a MWC based on [#marsaglia1999]_, but the Cong and\r\nSHR3 from [#marsaglia2003]_.\r\n\r\nFrom Pierre L'Ecuyer [#lecuyer1999]_ [#lecuyer1996]_, the Combined LFSR\r\n(Tausworthe) LFSR113 algorithm [#lfsr113]_ and LFSR88 (aka Taus88) have been\r\nimplemented.\r\n\r\n\r\nReferences\r\n``````````\r\n\r\n.. [#marsaglia1999] | `Random Numbers for C\\: End, at last?`__\r\n | George Marsaglia\r\n | Newsgroup post, sci.stat.math and others, Thu, 21 Jan 1999\r\n\r\n.. __:\r\n.. _Random Numbers for C\\: End, at last?:\r\n http://www.cse.yorku.ca/~oz/marsaglia-rng.html\r\n\r\n.. [#marsaglia2003] | `RNGs`__\r\n | George Marsaglia\r\n | Newsgroup post, sci.math, 26 Feb 2003\r\n\r\n.. __:\r\n.. _RNGs:\r\n http://groups.google.com/group/sci.math/msg/9959175f66dd138f\r\n\r\n.. [#rose] | `KISS: A Bit Too Simple`__\r\n | Greg Rose\r\n | Qualcomm Inc.\r\n\r\n.. __:\r\n.. _KISS\\: A Bit Too Simple:\r\n http://eprint.iacr.org/2011/007.pdf\r\n\r\n.. [#lecuyer1999] | `Tables of Maximally-Equidistributed Combined LFSR Generators`__\r\n | Pierre L'Ecuyer\r\n | Mathematics of Computation, 68, 225 (1999), 261\u2013269.\r\n\r\n.. __:\r\n.. _Tables of Maximally-Equidistributed Combined LFSR Generators:\r\n http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.43.3639\r\n\r\n.. [#lfsr113] | `LFSR113 C double implementation`__\r\n | Pierre L'Ecuyer\r\n\r\n.. __:\r\n.. _LFSR113 C double implementation:\r\n http://www.iro.umontreal.ca/~simardr/rng/lfsr113.c\r\n\r\n.. [#lecuyer1996] | `Maximally Equidistributed Combined Tausworthe Generators`__\r\n | P. L'Ecuyer\r\n | Mathematics of Computation, 65, 213 (1996), 203\u2013213.\r\n\r\n.. __:\r\n.. _Maximally Equidistributed Combined Tausworthe Generators:\r\n http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.43.4155\r\n\r\n\r\n----------------\r\nModules Provided\r\n----------------\r\n\r\n========================== ===========================================================================\r\nModule Description\r\n========================== ===========================================================================\r\n``simplerandom.iterators`` Iterator classes, which generate unsigned 32-bit integers.\r\n``simplerandom.random`` Classes that conform to standard Python ``random.Random`` API.\r\n========================== ===========================================================================\r\n\r\n\r\nRandom Number Generators Provided\r\n`````````````````````````````````\r\n\r\nIn ``simplerandom.iterators``, the following pseudo-random number generators are provided:\r\n\r\n========================== ===========================================================================\r\nGenerator Notes\r\n========================== ===========================================================================\r\n``MWC1`` Two 32-bit MWCs combined. From [#marsaglia1999]_.\r\n``MWC2`` Very similar to ``MWC1``, but slightly modified to improve its statistical properties.\r\n``Cong`` From [#marsaglia2003]_.\r\n``SHR3`` From [#marsaglia2003]_.\r\n``MWC64`` A single 64-bit multiply-with-carry calculation. From [#marsaglia2003]_.\r\n``KISS`` Combination of MWC2, Cong and SHR3. Based on [#marsaglia1999]_ but using Cong and SHR3 from [#marsaglia2003]_, and the modified MWC.\r\n``KISS2`` Combination of MWC64, Cong and SHR3. From [#marsaglia2003]_.\r\n``LFSR113`` Combined LFSR (Tausworthe) random number generator by L'Ecuyer. From [#lecuyer1999]_ [#lfsr113]_.\r\n``LFSR88`` Combined LFSR (Tausworthe) random number generator by L'Ecuyer. From [#lecuyer1996]_.\r\n========================== ===========================================================================\r\n\r\nThese generators are Python iterators, of infinite length (they never raise\r\n``StopIteration``). They implement the ``__next__()`` function to generate the\r\nnext random integer. All the generators output 32-bit unsigned values, and\r\ntake one or more 32-bit seed values during initialisation/seeding.\r\n\r\n\r\nIn ``simplerandom.random``, pseudo-random number generators are provided which\r\nhave the same names as those in ``simplerandom.iterators``, but these\r\ngenerators implement the standard Python ``random.Random`` API. Each generator\r\nuses the iterator of the same name in ``simplerandom.iterators`` to generate\r\nthe random bits used to produce the random floats. The ``jumpahead()`` function\r\n(in the style of the Python 2.x API) is implemented in all cases, even though\r\n``jumpahead()`` has officially been removed from the Python 3.x ``random`` API.\r\n\r\n\r\n-----\r\nUsage\r\n-----\r\n\r\nIterators\r\n`````````\r\n\r\n >>> import simplerandom.iterators as sri\r\n >>> rng = sri.KISS(123958, 34987243, 3495825239, 2398172431)\r\n >>> next(rng)\r\n 702862187\r\n >>> next(rng)\r\n 13888114\r\n >>> next(rng)\r\n 699722976\r\n\r\nRandom class API\r\n````````````````\r\n\r\n >>> import simplerandom.random as srr\r\n >>> rng = srr.KISS(258725234)\r\n >>> rng.random()\r\n 0.0925917826051541\r\n >>> rng.random()\r\n 0.02901686453730415\r\n >>> rng.random()\r\n 0.9024972981686489\r\n\r\n\r\n-------------------------\r\nSupported Python Versions\r\n-------------------------\r\n\r\nPython >= 3.10 are supported.\r\n\r\nPython versions < 3.10 might work, but have not been tested.\r\n\r\n\r\n-------------\r\nUse of Cython\r\n-------------\r\n\r\n`Cython`_ is used to make a fast implementation of ``simplerandom.iterators``.\r\nCython creates a ``.c`` file that can be compiled into a Python binary\r\nextension module.\r\n\r\nThe ``simplerandom`` source distribution package includes a ``.c`` file that\r\nwas created with Cython, so it is not necessary to have Cython installed to\r\ninstall ``simplerandom``.\r\n\r\nThe Cython ``.pyx`` file is also included, if you want to modify the Cython\r\nsource code, in which case you do need to have Cython installed. But by\r\ndefault, ``setup.py`` builds the extension from the ``.c`` file (to ensure\r\nthat the build doesn't fail due to particular Cython version issues). If you\r\nwish to build using Cython from the included ``.pyx`` file, you must set\r\n``USE_CYTHON=True`` in ``setup.py``.\r\n\r\n.. _Cython:\r\n http://cython.org/\r\n\r\n\r\n------------\r\nInstallation\r\n------------\r\n\r\nThe simplerandom package is installed using ``distutils``. If you have the tools\r\ninstalled to build a Python extension module, run the following command::\r\n\r\n python setup.py install\r\n\r\nIf you cannot build the C extension, you may install just the pure Python\r\nimplementation, using the following command::\r\n\r\n python setup.py build_py install --skip-build\r\n\r\n\r\n------------\r\nUnit Testing\r\n------------\r\n\r\nUnit testing of the iterators is in ``simplerandom.iterators.test``. It\r\nduplicates the tests of the C algorithms given in the original newsgroup post\r\n[#marsaglia1999]_, as well as other unit tests.\r\n\r\nTo run unit tests::\r\n\r\n python -m simplerandom.iterators.test\r\n\r\nA more thorough unit test suite is needed. A unit test suite for\r\n``simplerandom.random`` is needed.\r\n\r\n\r\n-------\r\nLicense\r\n-------\r\n\r\nThe code is released under the MIT license. See LICENSE.txt for details.\r\n\r\n",
"bugtrack_url": null,
"license": null,
"summary": "Simple random number generators",
"version": "0.13.8",
"project_urls": {
"Bug Tracker": "https://github.com/cmcqueen/simplerandom/issues",
"Homepage": "https://github.com/cmcqueen/simplerandom"
},
"split_keywords": [
"simple",
" random",
" pseudorandom",
" rng",
" prng"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "cee84d6e21bbd79696e1a139512771b9ccb51bfb930167065ca23650fb32f526",
"md5": "b6d58c481e395740573e618ab5e082b4",
"sha256": "bc4b3af288346e9bd48543e2cbded7e27dd4fc8cf11d37611a44da8793e46edc"
},
"downloads": -1,
"filename": "simplerandom-0.13.8-cp312-cp312-win32.whl",
"has_sig": false,
"md5_digest": "b6d58c481e395740573e618ab5e082b4",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.6",
"size": 165857,
"upload_time": "2025-07-23T00:30:34",
"upload_time_iso_8601": "2025-07-23T00:30:34.975176Z",
"url": "https://files.pythonhosted.org/packages/ce/e8/4d6e21bbd79696e1a139512771b9ccb51bfb930167065ca23650fb32f526/simplerandom-0.13.8-cp312-cp312-win32.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "7e3bf145a5426f653f8bb8d39dc06ae9e2f93eb231664dc5224c2268a7fc1541",
"md5": "ae98300ecae46d82f0168ff8a9ab8b06",
"sha256": "fdda2baa8f2372f2bd713d4eb60cd573c70e4bf4a0ae17a70bd37b60985aea64"
},
"downloads": -1,
"filename": "simplerandom-0.13.8-cp312-cp312-win_amd64.whl",
"has_sig": false,
"md5_digest": "ae98300ecae46d82f0168ff8a9ab8b06",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.6",
"size": 203702,
"upload_time": "2025-07-23T00:30:36",
"upload_time_iso_8601": "2025-07-23T00:30:36.723642Z",
"url": "https://files.pythonhosted.org/packages/7e/3b/f145a5426f653f8bb8d39dc06ae9e2f93eb231664dc5224c2268a7fc1541/simplerandom-0.13.8-cp312-cp312-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "55580d105d9ca18f88c3fe294ba77a4828daa3777e18305aa8505f16eb6299e4",
"md5": "cc235726c077942ec083f76c4c13f708",
"sha256": "277d7434907ba658ec4d01cf4794d7590a45e12b6daa4f99919f29a83fcaf432"
},
"downloads": -1,
"filename": "simplerandom-0.13.8-cp313-cp313-win32.whl",
"has_sig": false,
"md5_digest": "cc235726c077942ec083f76c4c13f708",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.6",
"size": 165985,
"upload_time": "2025-07-23T00:30:38",
"upload_time_iso_8601": "2025-07-23T00:30:38.834624Z",
"url": "https://files.pythonhosted.org/packages/55/58/0d105d9ca18f88c3fe294ba77a4828daa3777e18305aa8505f16eb6299e4/simplerandom-0.13.8-cp313-cp313-win32.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f86c5d14d77546338801ee906904155460b568861b46914ec4a76cfd156c43e1",
"md5": "6d59b11e3bb466d4f694e4ec6945fdcb",
"sha256": "92bc893a323aaa9f3d9a34540495987aee775387f0ac5c57f0883cf323b177eb"
},
"downloads": -1,
"filename": "simplerandom-0.13.8-cp313-cp313-win_amd64.whl",
"has_sig": false,
"md5_digest": "6d59b11e3bb466d4f694e4ec6945fdcb",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.6",
"size": 204474,
"upload_time": "2025-07-23T00:30:40",
"upload_time_iso_8601": "2025-07-23T00:30:40.576190Z",
"url": "https://files.pythonhosted.org/packages/f8/6c/5d14d77546338801ee906904155460b568861b46914ec4a76cfd156c43e1/simplerandom-0.13.8-cp313-cp313-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "6ecc0ea4b1b7973394523eb0711d4b88fedc7e1bbb00224717e6855e1717a980",
"md5": "8bebb2273c8c121eb0eac63d37b01c46",
"sha256": "c7adbc2cc2c778d84f99a6f18d4ff17b27780754962ea6ba9f65a8231b464fd3"
},
"downloads": -1,
"filename": "simplerandom-0.13.8.tar.gz",
"has_sig": false,
"md5_digest": "8bebb2273c8c121eb0eac63d37b01c46",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 408492,
"upload_time": "2025-07-23T00:30:41",
"upload_time_iso_8601": "2025-07-23T00:30:41.993835Z",
"url": "https://files.pythonhosted.org/packages/6e/cc/0ea4b1b7973394523eb0711d4b88fedc7e1bbb00224717e6855e1717a980/simplerandom-0.13.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-23 00:30:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "cmcqueen",
"github_project": "simplerandom",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "simplerandom"
}