scipy.stats.qmc.

Sobol#

class scipy.stats.qmc.Sobol(d, *, scramble=True, bits=None, seed=None, optimization=None)[源代码]#

用于生成(加扰的)索博尔序列的引擎。

索博尔序列是低差异的准随机数。可以使用两种方法绘制点

  • random_base2:安全地绘制 \(n=2^m\) 个点。此方法保证了序列的平衡属性。

  • random:从序列中绘制任意数量的点。请参见下面的警告。

参数:
dint

序列的维度。最高维度为 21201。

scramblebool,可选

如果为 True,则使用 LMS+shift 加扰。否则,不进行加扰。默认值为 True。

比特数int,可选

生成器的比特数。控制可生成的点最大值,即 2**bits。最大值为 64。它与始终为 np.float64 的返回类型不同,以防止点重复自身。默认值为 None,为了向后兼容,对应于 30。

在版本 1.9.0 中添加。

优化{None, “random-cd”, “lloyd”},可选

是否使用优化方案以改善采样后的质量。请注意,这是一个后处理步骤,不能保证保留样本的所有特性。默认值为 None。

  • random-cd:坐标的随机置换以降低中心化离散度。始终会根据中心化离散度更新最佳样本。与使用其他离散度度量相比,基于中心化离散度的采样对于 2D 和 3D 子投影显示出更好的空间填充鲁棒性。

  • lloyd:使用经修改的 Lloyd-Max 算法扰动样本。该过程会收敛到等距的样本。

在版本 1.10.0 中添加。

种子{None、int、numpy.random.Generator},可选

如果 seed 为 int 或 None,则使用 np.random.default_rng(seed) 创建新的 numpy.random.Generator。如果 seed 已是 Generator 实例,则使用提供的实例。

备注

Sobol 序列 [1] 提供了 \(n=2^m\) 个在 \([0,1)^{d}\) 中离散度低的点。对它们进行扰码 [3] 使它们适合于奇异积分,提供了误差估计的方法,并且可以提高它们的收敛速度。已实施的扰码策略是左线性矩阵扰码 (LMS),然后是数字随机移位 (LMS+移位) [2]

有许多版本的 Sobol 序列,具体取决于它们的“方向数”。此代码使用了 [4] 中的方向数。因此,维度最大数量是 21201。方向数已使用搜索准则 6 进行预计算,可在 https://web.maths.unsw.edu.au/~fkuo/sobol/ 检索。

警告

Sobol 序列是一种求积规则,如果样本大小不是 2 的幂,或跳过第一个点,或稀疏序列[5],那么它就会失去平衡特性。

如果 \(n=2^m\) 个点还不够,那么应针对 \(M>m\)\(2^M\) 个点。在随机处理时,重复次数 R 并不一定是 2 的幂。

Sobol 序列会生成一定数量的 \(B\) 位。在生成 \(2^B\) 个点后,序列就会重复。因此,会引发错误。位数可以通过参数 bits 来控制。

参考

[1]

I. M. Sobol',“立方体中的点分布和积分的精确求解。”Zh. Vychisl. Mat. i Mat. Phys.,7:784-802,1967 年。

[2]

J. Matousek,“锚盒的 L2 差异”。复杂性期刊 14,527-556,1998 年。

[3]

Art B. Owen,“置乱 Sobol 和 Niederreiter-Xing 点”。复杂性期刊,14(4):466-489,1998 年 12 月。

[4]

S. Joe 和 F. Y. Kuo,“构建投影效果更好的 Sobol 序列”。SIAM 科学计算期刊,30(5):2635-2654,2008 年。

[5]

Art B. Owen,“关于舍弃第一个 Sobol 点”。arXiv:2008.08051,2020 年。

示例

从 Sobol 低差异序列中生成样本。

>>> from scipy.stats import qmc
>>> sampler = qmc.Sobol(d=2, scramble=False)
>>> sample = sampler.random_base2(m=3)
>>> sample
array([[0.   , 0.   ],
       [0.5  , 0.5  ],
       [0.75 , 0.25 ],
       [0.25 , 0.75 ],
       [0.375, 0.375],
       [0.875, 0.875],
       [0.625, 0.125],
       [0.125, 0.625]])

使用差异准则计算样本质量。

>>> qmc.discrepancy(sample)
0.013882107204860938

为继续现有设计,可以通过再次调用 random_base2 来获取更多点。或者,还可以像下面这样跳过一些点:

>>> _ = sampler.reset()
>>> _ = sampler.fast_forward(4)
>>> sample_continued = sampler.random_base2(m=2)
>>> sample_continued
array([[0.375, 0.375],
       [0.875, 0.875],
       [0.625, 0.125],
       [0.125, 0.625]])

最后,样本可以缩放至界限。

>>> l_bounds = [0, 2]
>>> u_bounds = [10, 5]
>>> qmc.scale(sample_continued, l_bounds, u_bounds)
array([[3.75 , 3.125],
       [8.75 , 4.625],
       [6.25 , 2.375],
       [1.25 , 3.875]])

方法

fast_forward(n)

将序列快速前进 n 个位置。

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

l_bounds(包括)到 u_bounds(不包括),或如果 endpoint=True,则从 l_bounds(包括)到 u_bounds(包括)绘制 n 个整数。

random([n, workers])

在半开区间 [0, 1) 中绘制 n

random_base2(m)

从 Sobol's 序列中绘制点。

reset()

将引擎重置为基本状态。