I would like to use a quasi-random sequence, specifically Sobol, within a SciPy based simulation. Any recommendations on existing, efficient packages?
Is this project any use? If not, the relevant Wikipedia article mentions C and Fortran routines in NAG and Numerical Recipes, which probably shouldn't be difficult to wrap or reimplement in Python. There are also C routines in GSL.
I would use OpenTURNS, which provides several low discrepancy sequences:
Moreover, the sequence can be generated so that the marginals have arbitrary distribution. This is done with an probabilistic transformation, based on the inverse distribution function.
In the following example, I generate a Sobol' sequence in 2 dimensions, based on the LowDiscrepancyExperiment
class. The marginals are uniform in the [-1, 1] interval (which is the default Uniform distribution in OT). I suggest to use a sample size equal to a power of 2, because Sobol' sequence is based on base-2 integer decomposition. The generate
method returns a ot.Sample
.
import openturns as ot
dim = 2
distribution = ot.ComposedDistribution([ot.Uniform()]*dim)
bounds = distribution.getRange()
sequence = ot.SobolSequence(dim)
samplesize = 2**5 # Sobol' sequences are in base 2
experiment = ot.LowDiscrepancyExperiment(sequence, distribution,
samplesize, False)
sample = experiment.generate()
print(samplesize[:5])
The previous sample has size 32. The first 5 elements are:
y0 y1
0 0 0
1 0.5 -0.5
2 -0.5 0.5
3 -0.25 -0.25
4 0.75 0.75
The Sobol' sequence in OT can generate an arbitrary sample size, in dimensions up to 1111.
With a little more work, we may plot the design.
import openturns.viewer as otv
fig = otv.PlotDesign(sample, bounds, 2**2, 2**1);
fig.set_size_inches(6, 6)
which produces:
See how there is exactly 4 points in each elementary interval.
If required, the sample
can be easily converted into a Numpy array, which may better fits into your Scipy requirement:
import numpy as np
array = np.array(sample)
Other examples are provided at: http://openturns.github.io/openturns/master/examples/reliability_sensitivity/design_of_experiments.html
For Sobol Sequences try sobol_seq.
Generally speaking the best package I've found for dealing with quasirandom sequences is diversipy.
There are also packages that focus on specific implementations, for example sudoku_lhs deals with Latin Hypercubes and the Sudoku-type Constraint variant.
pyDOE implements at least Latin Hypercube (maybe more).
The most interesting package I found is py-design, which creates a wrapper for Fortran 90 codes on 15 or so methods. Unfortunately it does not seem to work (some assets seem to be missing).
Chaospy is also a valid option. It allows to select several approaches towards low-discrepancy sampling (including 'Sobol, latin hypercube, etc) - for more details see the documentation.
In the context of sensivity analysis SALib library seems interesting It has a Sobol sample generator and uses SciPy. Link here : https://salib.readthedocs.io/en/latest/