I would like to use a quasi-random sequence, specifically Sobol, within a SciPy based simulation. Any recommendations on existing, efficient packages?
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/latest/auto_reliability_sensitivity/index.html#design-of-experiments