class_docstr: A generic Quasi-Monte Carlo sampler class meant for subclassing.
  
  QMCEngine is a base class to construct a specific Quasi-Monte Carlo
  sampler. It cannot be used directly as a sampler.
  
  Parameters
  ----------
  d : int
      Dimension of the parameter space.
  seed : {None, int, `numpy.random.Generator`}, optional
      If `seed` is None the `numpy.random.Generator` singleton is used.
      If `seed` is an int, a new ``Generator`` instance is used,
      seeded with `seed`.
      If `seed` is already a ``Generator`` instance then that instance is
      used.
  
  Notes
  -----
  By convention samples are distributed over the half-open interval
  ``[0, 1)``. Instances of the class can access the attributes: ``d`` for
  the dimension; and ``rng`` for the random number generator (used for the
  ``seed``).
  
  **Subclassing**
  
  When subclassing `QMCEngine` to create a new sampler,  ``__init__`` and
  ``random`` must be redefined.
  
  * ``__init__(d, seed=None)``: at least fix the dimension. If the sampler
    does not take advantage of a ``seed`` (deterministic methods like
    Halton), this parameter can be omitted.
  * ``random(n)``: draw ``n`` from the engine and increase the counter
    ``num_generated`` by ``n``.
  
  Optionally, two other methods can be overwritten by subclasses:
  
  * ``reset``: Reset the engine to it's original state.
  * ``fast_forward``: If the sequence is deterministic (like Halton
    sequence), then ``fast_forward(n)`` is skipping the ``n`` first draw.
  
  Examples
  --------
  To create a random sampler based on ``np.random.random``, we would do the
  following:
  
  >>> from scipy.stats import qmc
  >>> class RandomEngine(qmc.QMCEngine):
  ...     def __init__(self, d, seed=None):
  ...         super().__init__(d=d, seed=seed)
  ...
  ...
  ...     def random(self, n=1):
  ...         self.num_generated += n
  ...         return self.rng.random((n, self.d))
  ...
  ...
  ...     def reset(self):
  ...         super().__init__(d=self.d, seed=self.rng_seed)
  ...         return self
  ...
  ...
  ...     def fast_forward(self, n):
  ...         self.random(n)
  ...         return self
  
  After subclassing `QMCEngine` to define the sampling strategy we want to
  use, we can create an instance to sample from.
  
  >>> engine = RandomEngine(2)
  >>> engine.random(5)
  array([[0.22733602, 0.31675834],  # random
         [0.79736546, 0.67625467],
         [0.39110955, 0.33281393],
         [0.59830875, 0.18673419],
         [0.67275604, 0.94180287]])
  
  We can also reset the state of the generator and resample again.
  
  >>> _ = engine.reset()
  >>> engine.random(5)
  array([[0.22733602, 0.31675834],  # random
         [0.79736546, 0.67625467],
         [0.39110955, 0.33281393],
         [0.59830875, 0.18673419],
         [0.67275604, 0.94180287]])
class_docstr_tok: ["A","generic","Quasi-Monte","Carlo","sampler","class","meant","for","subclassing",".","QMCEngine","is","a","base","class","to","construct","a","specific","Quasi-Monte","Carlo","sampler",".","It","can","not","be","used","directly","as","a","sampler",".","Parameters","--","--","--","--","--","d",":","int","Dimension","of","the","parameter","space",".","seed",":","{","None",",","int",",","`","numpy.random.Generator","`","}",",","optional","If","`","seed","`","is","None","the","`","numpy.random.Generator","`","singleton","is","used",".","If","`","seed","`","is","an","int",",","a","new","``","Generator","``","instance","is","used",",","seeded","with","`","seed","`",".","If","`","seed","`","is","already","a","``","Generator","``","instance","then","that","instance","is","used",".","Notes","--","--","-","By","convention","samples","are","distributed","over","the","half-open","interval","``","[","0",",","1",")","``",".","Instances","of","the","class","can","access","the","attributes",":","``","d","``","for","the","dimension",";","and","``","rng","``","for","the","random","number","generator","(","used","for","the","``","seed","``",")",".","*","*","Subclassing","*","*","When","subclassing","`","QMCEngine","`","to","create","a","new","sampler",",","``","__init__","``","and","``","random","``","must","be","redefined",".","*","``","__init__","(","d",",","seed=None",")","``",":","at","least","fix","the","dimension",".","If","the","sampler","does","not","take","advantage","of","a","``","seed","``","(","deterministic","methods","like","Halton",")",",","this","parameter","can","be","omitted",".","*","``","random","(","n",")","``",":","draw","``","n","``","from","the","engine","and","increase","the","counter","``","num_generated","``","by","``","n","``",".","Optionally",",","two","other","methods","can","be","overwritten","by","subclasses",":","*","``","reset","``",":","Reset","the","engine","to","it","'s","original","state",".","*","``","fast_forward","``",":","If","the","sequence","is","deterministic","(","like","Halton","sequence",")",",","then","``","fast_forward","(","n",")","``","is","skipping","the","``","n","``","first","draw",".","Examples","--","--","--","--","To","create","a","random","sampler","based","on","``","np.random.random","``",",","we","would","do","the","following",":",">",">",">","from","scipy.stats","import","qmc",">",">",">","class","RandomEngine","(","qmc.QMCEngine",")",":","...","def","__init__","(","self",",","d",",","seed=None",")",":","...","super","(",")",".__init__","(","d=d",",","seed=seed",")","...","...","...","def","random","(","self",",","n=1",")",":","...","self.num_generated","+=","n","...","return","self.rng.random","(","(","n",",","self.d",")",")","...","...","...","def","reset","(","self",")",":","...","super","(",")",".__init__","(","d=self.d",",","seed=self.rng_seed",")","...","return","self","...","...","...","def","fast_forward","(","self",",","n",")",":","...","self.random","(","n",")","...","return","self","After","subclassing","`","QMCEngine","`","to","define","the","sampling","strategy","we","want","to","use",",","we","can","create","an","instance","to","sample","from",".",">",">",">","engine","=","RandomEngine","(","2",")",">",">",">","engine.random","(","5",")","array","(","[","[","0.22733602",",","0.31675834","]",",","#","random","[","0.79736546",",","0.67625467","]",",","[","0.39110955",",","0.33281393","]",",","[","0.59830875",",","0.18673419","]",",","[","0.67275604",",","0.94180287","]","]",")","We","can","also","reset","the","state","of","the","generator","and","resample","again",".",">",">",">","_","=","engine.reset","(",")",">",">",">","engine.random","(","5",")","array","(","[","[","0.22733602",",","0.31675834","]",",","#","random","[","0.79736546",",","0.67625467","]",",","[","0.39110955",",","0.33281393","]",",","[","0.59830875",",","0.18673419","]",",","[","0.67275604",",","0.94180287","]","]",")"]
code: def __init__(self, d: IntNumber, *, seed: SeedType = None) -> None:
      if not np.issubdtype(type(d), np.integer):
          raise ValueError("d must be an integer value")
  
      self.d = d
      self.rng = check_random_state(seed)
      self.rng_seed = copy.deepcopy(seed)
      self.num_generated = 0
  
imports: from __future__ import annotations
  import os
  import copy
  import numbers
  from abc import ABC, abstractmethod
  import math
  from typing import ClassVar, List, Optional, overload, TYPE_CHECKING
  import warnings
  import numpy
  import scipy.stats
  from scipy._lib._util import rng_integers
  from scipy.stats._sobol import initialize_v, _cscramble, _fill_p_cumulative, _draw, _fast_forward, _categorize, initialize_direction_numbers, _MAXDIM, _MAXBIT
  from scipy.stats._qmc_cy import _cy_wrapper_centered_discrepancy, _cy_wrapper_wrap_around_discrepancy, _cy_wrapper_mixture_discrepancy, _cy_wrapper_l2_star_discrepancy, _cy_wrapper_update_discrepancy
label_desc: Use image node_id 1 to create a new QMCEngine object from inherited base classes: ABC with example: obj = QMCEngine(d)