兼容性策略#
numpy.random 具有比 NumPy 其余部分略为严格的兼容性策略.伪随机性的用户通常需要能够重现相同种子下的详细运行(所谓的"流兼容性"),因此我们尝试在这些需求与增强算法的灵活性之间取得平衡. NEP 19 描述了此策略的演变.
我们强制执行的主要兼容性类型是在某些条件下从一次运行到另一次运行的流兼容性.如果您使用相同的 BitGenerator 创建一个 Generator ,使用相同的种子,在相同的 numpy 构建版本,相同的环境和相同的机器上执行相同的方法调用序列并使用相同的参数,则应获得相同的数字流.请注意,这些条件非常严格.NumPy 控制之外的许多因素限制了我们保证超出此范围的能力.例如,不同的 CPU 以不同的方式实现浮点运算,这可能会导致某些极端情况的差异,从而影响到流的其余部分.例如, Generator.multivariate_normal 使用来自 numpy.linalg 的矩阵分解.即使在相同的平台上, numpy 的不同构建版本也可能使用来自它链接到的 LAPACK 的不同版本的矩阵分解算法,从而导致 Generator.multivariate_normal 返回完全不同(但同样有效!)的结果.我们努力首选对这些影响更具抵抗力的算法,但这始终是不完美的.
备注
大多数 Generator 方法允许您从分布中抽取多个值作为数组.此数组的请求大小是一个参数,用于上述策略的目的.不能保证调用 rng.random() 5 次与调用 rng.random(5) 得到相同的数字.我们保留决定对不同大小的块使用不同算法的能力.在实践中,这种情况很少发生.
与 NumPy 的其余部分一样,我们通常保持版本之间的 API 源代码兼容性.如果我们必须进行 API 破坏性更改,那么我们将仅根据 general NumPy policy ,在适当的弃用期和警告后进行.
允许打破流兼容性以引入新功能或提高 Generator 或 default_rng 的性能,但需要谨慎.此类更改将被视为特性,因此不会比特性的标准发布节奏(即在 X.Y 版本上,而不是 X.Y.Z 上)更快.为此,速度慢将不被视为错误.像往常一样,破坏流兼容性的正确性错误修复可能会在错误修复版本中发生,但开发人员应考虑是否可以等到下一个特性版本.我们鼓励开发人员强烈权衡用户因流兼容性中断而带来的痛苦与改进之间的关系.一个值得改进的例子是更改算法以显着提高性能,例如,将高斯变量生成的 Box-Muller transform 方法更改为更快的 Ziggurat algorithm .一个不鼓励的改进的例子是稍微调整 Ziggurat 表,以获得较小的性能提升.
备注
特别是,允许 default_rng 更改它使用的默认 BitGenerator (同样,要谨慎并提前发出大量警告).
通常, BitGenerator 类对版本之间的流兼容性有更强的保证.这使得它们成为下游用户需要它的更坚实的构建块.它们有限的 API 表面使它们更容易从一个版本到另一个版本保持这种兼容性.有关其各自的兼容性保证,请参阅每个 BitGenerator 类的文档字符串.
传统的 RandomState 和 associated convenience functions 具有更严格的版本间兼容性保证. 由于 NEP 19 中概述的原因,我们在 NumPy 开发初期就对其版本间稳定性做出了更强的承诺. 这种兼容性仍然存在一些有限的用例(例如为测试生成数据),因此我们尽可能保持兼容性. RandomState 将不再进行任何修改,即使是修复正确性错误也不行. 在一些灰色地带,我们可以进行小的修复,以保持 RandomState 正常工作,而不会因 NumPy 内部结构的更改而导致段错误,以及一些文档字符串修复. 然而,先前关于机器之间和构建之间可变性的警告仍然适用于 RandomState ,就像它适用于 Generator 一样.