LintSampler#

class lintsampler.LintSampler(domain, pdf=None, vectorizedpdf=False, pdf_args=(), pdf_kwargs={}, seed=None, qmc=False, qmc_engine=None)#

Linear interpolant sampler for arbitrary probability density function.

LintSampler takes a primary argument, domain, which is the region within which sampling takes place. After instantiation, the sample method realises the random sampling of the given pdf on the domain. The sampling may either take place at random (default), or in a low-discrepancy sequence (with qmc=True).

See the parameters below for additional control options, and further examples below for the various usage patterns.

Parameters:
domainiterable or DensityStructure

Coordinate grid(s) to draw samples over. Several forms are available. If using a single coordinate grid, then domain can be any of:

  • a 1D iterable (array, list, tuple) representing the cell edges of a 1D grid. So, if the grid has N cells, then the iterable should have N+1 elements.

  • a tuple of 1D iterables, representing the cell edges of a kD grid. If the grid has (N1, N2, …, Nk) cells, then the tuple should have length k, and the 1D arrays in the tuple should have lengths N1+1, N2+1, …, Nk+1.

  • a DensityStructure subclass instance. In this case, pdf parameter should not be set, as a PDF has already been evaluated over the DensityStructure.

If using multiple (non-overlapping) coordinate grids, then domain should be a list of any of the above. See the examples below for the various usage patterns.

pdf{None, function}, optional

Probability density function from which to draw samples. Function should take coordinate vector (or batch of vectors if vectorized; see vectorizedpdf parameter) and return (unnormalised) density (or batch of densities if vectorized). Additional arguments can be passed to the function via pdf_args and pdf_kwargs parameters. Default is None, in which case it is assumed that domain parameter comprises one instance or a list of several instances of DensityStructure.

vectorizedpdfbool, optional

if True, assumes that the pdf function is vectorized, i.e., it accepts (…, dim)-shaped batches of coordinate vectors and returns (…)-shaped batches of densities. If False, assumes that the pdf function simply accepts (dim,)-shaped coordinate vectors (or floats in the univariate case) and returns single densities. Default is False.

pdf_argstuple, optional

Additional positional arguments to pass to pdf function; function call is pdf(position, *pdf_args, **pdf_kwargs). Default is empty tuple (no additional positional arguments).

pdf_kwargsdict, optional

Additional keyword arguments to pass to pdf function; function call is pdf(position, *pdf_args, **pdf_kwargs). Default is empty dict (no additional keyword arguments).

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

Seed for numpy random generator. Can be random generator itself, in which case it is left unchanged. Can also be an integer seed for a generator instance. Default is None, in which case new default generator is created. See numpy random generator docs for more information.

qmcbool, optional

Whether to use Quasi-Monte Carlo sampling. Default is False.

qmc_engine{None, scipy.stats.qmc.QMCEngine}, optional

Quasi-Monte Carlo engine to use if qmc flag above is True. Should be subclass of scipy QMCEngine, e.g. qmc.Sobol. Should have dimensionality dim``+1, because first ``dim dimensions are used for lintsampling, while last dimension is used for cell choice (this happens even if only one cell is given). Default is None. In that case, if qmc is True, then a scrambled Sobol sequence is used.

Examples

These examples demonstrate the multiple ways to use LintSampler. In each case, we’ll just generate densities from a uniform distribution, but in general they might come from any arbitrary density function.

1. A single sample from a 1D grid. The grid spans x=0 to x=10, and has 32 cells (so 33 edges).

>>> cells = np.linspace(0, 10, 33)
>>> def pdfrandom(X): return np.random.uniform()
>>> LintSampler(cells,pdf=pdfrandom).sample()
6.984134639227398

This returns a single scalar: the sampling point within the grid.

2. Multiple samples from a 1D grid (same grid as previous example). Now also demonstrating a vectorized pdf for efficiency when N becomes large.

>>> cells = np.linspace(0, 10, 33)
>>> def pdfrandom(X): return np.random.uniform(size=X.shape[0])
>>> LintSampler(cells,pdf=pdfrandom,vectorizedpdf=True).sample(N=4)
array([8.16447008, 5.30536088, 8.96135879, 7.73572977])

This returns a 1D array: the N sampling points within the grid.

3. Single sample from a k-D grid. In this case we’ll take a 2D grid, with 32 x 64 cells (so 33 gridlines along one axis and 65 along the other).

>>> x = np.linspace(0, 10, 33)
>>> y = np.linspace(100, 200, 65)
>>> cells = (x,y)
>>> def pdfrandom(X): return np.random.uniform()
>>> LintSampler(cells,pdf=pdfrandom).sample()
array([  7.67294632, 190.45302915])

This returns a 1D array: the single k-D sampling point within the grid.

  1. Multiple samples from a k-D grid (same grid as previous example).

>>> x = np.linspace(0, 10, 33)
>>> y = np.linspace(100, 200, 65)
>>> cells = (x,y)
>>> def pdfrandom(X): return np.random.uniform()
>>> LintSampler(cells,pdf=pdfrandom).sample(N=5)
array([[1.35963966e-01, 1.38182930e+02],
       [6.52704300e+00, 1.63109912e+02],
       [4.35226761e+00, 1.49753235e+02],
       [3.56093155e+00, 1.48548481e+02],
       [1.31163401e+00, 1.59335676e+02]])

This returns a 2D array, shape (N, k): the N k-D samples within the grid.

5. A DensityGrid instance may also be passed to any of the above examples. See the DensityGrid documentation for details. In this case, one need not pass a pdf.

>>> x = np.linspace(0, 10, 33)
>>> y = np.linspace(100, 200, 65)
>>> def pdfrandom(X): return np.random.uniform()
>>> g = DensityGrid((x, y), pdfrandom)
>>> LintSampler(g).sample()
array([  1.417842  , 139.40070095])
Attributes:
pdf{None, function}

PDF function to evaluate on grid. None if densities pre-evaluated. See corresponding parameter above.

vectorizedpdfbool

Whether pdf function is vectorized. See corresponding parameter above.

pdf_argstuple

Additional positional arguments for pdf function. See corresponding parameter above.

pdf_kwargsdict

Additional keyword arguments for pdf function. See corresponding parameter above.

dimint

Dimensionality of PDF / coordinate space.

gridslist

List of DensityStructure instances corresponding to series of sampling domains passed in domain parameter. Single list element if only one domain passed.

ngridsint

Number of domains to sample over (i.e., length of grids attribute).

qmcbool

Whether to use Quasi-Monte Carlo sampling. See corresponding parameter above.

rngnumpy.random.Generator

Random generator used for generating samples. Used alongside Quasi-Monte Carlo engine if qmc is True.

qmc_engine{None, scipy.stats.qmc.QMCEngine}

Quasi-Monte Carlo engine used for generating samples if qmc is True.

Methods

reset_domain(domain)

Reset the sampling grid(s) without changing the pdf.

sample([N])

Draw samples from the pdf on the constructed grid(s).

reset_domain(domain)#

Reset the sampling grid(s) without changing the pdf.

Parameters:
domainiterable or DensityGrid

See domain entry in documentation for class constructor.

Returns:
None
sample(N=None)#

Draw samples from the pdf on the constructed grid(s).

This function draws a sample (or N samples) from the given PDF over the given grid(s). It first chooses a grid (or N grids with replacement), weighting them by their total mass, then similarly chooses a cell (or N cells), then samples from the k-linear interpolant within the chosen cell(s).

Parameters:
N{None, int}, optional

Number of samples to draw. Default is None, in which case a single sample is drawn.

Returns:
Xscalar, 1D array (length k OR N) or 2D array (N, k)

Sample(s) from linear interpolant. Scalar if single sample (i.e., N is None) in 1D. 1D array if single sample in k-D OR multiple samples in 1D. 2D array if multiple samples in k-D.