class scipy.stats.qmc.Halton(d, *, scramble=True, optimization=None, seed=None)[source]#

Halton sequence.

Pseudo-random number generator that generalize the Van der Corput sequence for multiple dimensions. The Halton sequence uses the base-two Van der Corput sequence for the first dimension, base-three for its second and base-\(n\) for its n-dimension.


Dimension of the parameter space.

scramblebool, optional

If True, use Owen scrambling. Otherwise no scrambling is done. Default is True.

optimization{None, “random-cd”, “lloyd”}, optional

Whether to use an optimization scheme to improve the quality after sampling. Note that this is a post-processing step that does not guarantee that all properties of the sample will be conserved. Default is None.

  • random-cd: random permutations of coordinates to lower the centered discrepancy. The best sample based on the centered discrepancy is constantly updated. Centered discrepancy-based sampling shows better space-filling robustness toward 2D and 3D subprojections compared to using other discrepancy measures.

  • lloyd: Perturb samples using a modified Lloyd-Max algorithm. The process converges to equally spaced samples.

Added in version 1.10.0.

seed{None, int, numpy.random.Generator}, optional

If seed is an int or None, a new numpy.random.Generator is created using np.random.default_rng(seed). If seed is already a Generator instance, then the provided instance is used.


The Halton sequence has severe striping artifacts for even modestly large dimensions. These can be ameliorated by scrambling. Scrambling also supports replication-based error estimates and extends applicabiltiy to unbounded integrands.



Halton, “On the efficiency of certain quasi-random sequences of points in evaluating multi-dimensional integrals”, Numerische Mathematik, 1960.


A. B. Owen. “A randomized Halton algorithm in R”, arXiv:1706.02808, 2017.


Generate samples from a low discrepancy sequence of Halton.

>>> from scipy.stats import qmc
>>> sampler = qmc.Halton(d=2, scramble=False)
>>> sample = sampler.random(n=5)
>>> sample
array([[0.        , 0.        ],
       [0.5       , 0.33333333],
       [0.25      , 0.66666667],
       [0.75      , 0.11111111],
       [0.125     , 0.44444444]])

Compute the quality of the sample using the discrepancy criterion.

>>> qmc.discrepancy(sample)

If some wants to continue an existing design, extra points can be obtained by calling again random. Alternatively, you can skip some points like:

>>> _ = sampler.fast_forward(5)
>>> sample_continued = sampler.random(n=5)
>>> sample_continued
array([[0.3125    , 0.37037037],
       [0.8125    , 0.7037037 ],
       [0.1875    , 0.14814815],
       [0.6875    , 0.48148148],
       [0.4375    , 0.81481481]])

Finally, samples can be scaled to bounds.

>>> l_bounds = [0, 2]
>>> u_bounds = [10, 5]
>>> qmc.scale(sample_continued, l_bounds, u_bounds)
array([[3.125     , 3.11111111],
       [8.125     , 4.11111111],
       [1.875     , 2.44444444],
       [6.875     , 3.44444444],
       [4.375     , 4.44444444]])



Fast-forward the sequence by n positions.

integers(l_bounds, *[, u_bounds, n, ...])

Draw n integers from l_bounds (inclusive) to u_bounds (exclusive), or if endpoint=True, l_bounds (inclusive) to u_bounds (inclusive).

random([n, workers])

Draw n in the half-open interval [0, 1).


Reset the engine to base state.