diff --git a/docs/source/how_to.rst b/docs/source/how_to.rst index 809a47f..4499a65 100644 --- a/docs/source/how_to.rst +++ b/docs/source/how_to.rst @@ -1,4 +1,87 @@ How-to Guides ============= -To be written. \ No newline at end of file +How to save and resume long computation +--------------------------------------- + +:class:`RandomState` is pickleable, and pickling allows to save and restore +the internal state of the quasi-random number generators. + +.. code-block:: python + :caption: Saving state of quasi-random basic random number generators + + import numpy as np + import mkl_random + import pickle + + rs = mkl_random.RandomState(seed=777, brng="r250") + draw = rs.standard_normal(size=1357913) + + # pickle random state + saved = pickle.dumps(rs) + + # draw some numbers as if computation were to continue + post_draw = rs.gamma(5, 1, size=100) + + # restore random state, and continue from + restored_rs = pickle.loads(saved) + resumed_draw = restored_rs.gamma(5, 1, size=100) + + # sample from restored stated is the same as sample + # from the original one + assert np.array_equal(restored_rs, resumed_draw) + + +Stochastic computations in parallel with multiprocessing +-------------------------------------------------------- + +When performing stochastic computations in parallel, care is due to ensure +statistical independence of samples drawn in parallel. + +Basic quasi-random number generators provide different means to accomplishing +this. Some support :meth:`skipahead` method or :meth:`leapfrog` method, while +others provide a fixed-size family of generators with nice property that generators +from such family, initialized equally, produce streams of randomness statistically +indistunguishable from independent. + +.. py:method:: skipahead(nskips) + :canonical: mkl_random.RandomState.skipahead + + Advance the state of the generator using skip-ahead method, or raise :code:`ValueError` + exception if not supported. + + The argument `nskips` must be a positive Python integer. + + The method is supported for :ref:`"philox4x32x10" `, :ref:`"mrg32k3a" `, + :ref:`"mcg31m1" `, :ref:`"mcg59" `, :ref:`"wh" `, + :ref:`"mt19937" `, :ref:`"sfmt19937" `, and :ref:`"ars5" ` + basic random number generators. + +.. note:: + When using :meth:`skipahead`, it is important to ensure that a parallel task does not consume more than + :code:`nskips` states, otherwise streams of randomness begin to overlap and the assumption of statistical + independence breaks down. + +.. py:method:: leapfrog(k, nstreams) + :canonical: mkl_random.RandomState.leapfrog + + Initialize the state of the generator using leap-frog method, or raise :code:`ValueError` + exception if not supported. + + The leap-frog method partitions state tragectory into :code:`nstream` interleaved non-overlapping + sub-sequences, and argument :code:`k` identifies the subsequence. + + The method is supported for :ref:`"mcg31m1" `, :ref:`"mcg59" `, and :ref:`"wh" ` + basic pseudo-random number generators. + +.. note:: + When using :meth:`leapfrog` or :meth:`skipahead` methods one must remember that parallel tasks partition + generators period and choose a generator with sufficiently long period to avoid cycling over the period + more than once, as doing so also breaks the assumption of statistical independence and may compromise + correctness of the simulation. + +:mod:`mkl_random` also provides two families of basic pseudo-random number generators, :ref:`"mt2203" ` and +:ref:`"wh" `, with property that members from particular family, initialized equally, produce streams of +randomness stasistically indistunguishable from independent. To use such families in parallel computation, assign +difference family generators to different parallel workers and sample those assigned generators in each parallel worker. +Please refer to "examples/" folder in the `GitHub repo `_ for more details. \ No newline at end of file diff --git a/docs/source/reference/ars5.rst b/docs/source/reference/ars5.rst index 0a91c02..92f6ff4 100644 --- a/docs/source/reference/ars5.rst +++ b/docs/source/reference/ars5.rst @@ -1,3 +1,5 @@ +.. _ars5_brng: + ARS5 brng ========= diff --git a/docs/source/reference/mcg31.rst b/docs/source/reference/mcg31.rst index 87ee301..1076644 100644 --- a/docs/source/reference/mcg31.rst +++ b/docs/source/reference/mcg31.rst @@ -1,3 +1,5 @@ +.. _mcg31m1_brng: + MCG31 brng ========== diff --git a/docs/source/reference/mcg59.rst b/docs/source/reference/mcg59.rst index 314361a..e187ba6 100644 --- a/docs/source/reference/mcg59.rst +++ b/docs/source/reference/mcg59.rst @@ -1,3 +1,5 @@ +.. _mcg59_brng: + MCG59 brng ========== diff --git a/docs/source/reference/mrg32k3a.rst b/docs/source/reference/mrg32k3a.rst index 54c5c7e..24465f6 100644 --- a/docs/source/reference/mrg32k3a.rst +++ b/docs/source/reference/mrg32k3a.rst @@ -1,3 +1,5 @@ +.. _mrg32k3a_brng: + MRG32k3a brng ============= diff --git a/docs/source/reference/mt19937.rst b/docs/source/reference/mt19937.rst index 6b32777..729ee16 100644 --- a/docs/source/reference/mt19937.rst +++ b/docs/source/reference/mt19937.rst @@ -1,3 +1,5 @@ +.. _mt19937_brng: + MT19937 brng ============ diff --git a/docs/source/reference/mt2203.rst b/docs/source/reference/mt2203.rst index 6bf43a5..db815ae 100644 --- a/docs/source/reference/mt2203.rst +++ b/docs/source/reference/mt2203.rst @@ -1,3 +1,5 @@ +.. _mt2203_brng: + MT2203 brng =========== diff --git a/docs/source/reference/nondeterministic.rst b/docs/source/reference/nondeterministic.rst index a3b2212..68a5435 100644 --- a/docs/source/reference/nondeterministic.rst +++ b/docs/source/reference/nondeterministic.rst @@ -1,3 +1,5 @@ +.. _nondeterm_brng: + Nondeterm brng ============== diff --git a/docs/source/reference/philox4x32x10.rst b/docs/source/reference/philox4x32x10.rst index 9eb5ae1..05a0d33 100644 --- a/docs/source/reference/philox4x32x10.rst +++ b/docs/source/reference/philox4x32x10.rst @@ -1,3 +1,5 @@ +.. _philox4x32x10_brng: + Philox4x32x10 brng ================== diff --git a/docs/source/reference/r250.rst b/docs/source/reference/r250.rst index 5f1c5a5..75b1acd 100644 --- a/docs/source/reference/r250.rst +++ b/docs/source/reference/r250.rst @@ -1,3 +1,5 @@ +.. _r250_brng: + R250 brng ========= diff --git a/docs/source/reference/sfmt19937.rst b/docs/source/reference/sfmt19937.rst index db6c53f..f9e84d9 100644 --- a/docs/source/reference/sfmt19937.rst +++ b/docs/source/reference/sfmt19937.rst @@ -1,3 +1,5 @@ +.. _sfmt19937_brng: + SFMT19937 brng ============== diff --git a/docs/source/reference/wichmann_hill.rst b/docs/source/reference/wichmann_hill.rst index b0128dc..a463945 100644 --- a/docs/source/reference/wichmann_hill.rst +++ b/docs/source/reference/wichmann_hill.rst @@ -1,3 +1,5 @@ +.. _wh_brng: + Wichmann-Hill brng ================== diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst index faeb59a..53f8798 100644 --- a/docs/source/tutorials.rst +++ b/docs/source/tutorials.rst @@ -1,5 +1,8 @@ +Beginner's guide +================ + Installation -============ +------------ Package :mod:`mkl_random` is available in conda ecosystem on "conda-forge", default, and "intel" channels. @@ -32,8 +35,8 @@ The package can also be installed via :code:`pip`, either from PyPI, or from The :mod:`mkl_random` is also distributed as part of `Intel(R) Distribution for Python* `_. -Beginner's guide -================ +First steps +----------- The :mod:`mkl_random` package was designed following :class:`numpy.random.RandomState` class to make use of :mod:`mkl_random` easy for current uses of :mod:`numpy.random` module.