如何在 python 中生成至少 20 位小数的种子随机浮点数?

How to generate seeded random floats of at least 20 decimal places in python?

我想在 -1 到 1 的范围内生成至少 20 位小数的种子随机浮点数。

import numpy as np
np.random.seed(2000)
np.random.uniform(low=-1, high=1, size=2)

这是我过去会做的,但我的 DOE 研究需要更精确。

我查看了 python

中的 mpmath 和 decimal 模块
import mpmath
mpmath.mp.dps = 22
xis = (mpmath.rand() - mpmath.mpf(1), mpmath.rand())

这不起作用,因为我找不到种子 mpmath.mp.rand()

import numpy as np
from decimal import Decimal, getcontext

getcontext().prec = 20
xis = np.asarray([Decimal(f"{x}") x for x in np.random.uniform(low=-1, high=1, size=2)], dtype=np.float64)

在这里,我的浮点数依赖于 numpy,并且最多有 16-7 位小数。

如何创建小数点后 20 位以上且可播种的随机浮点数?

首先,您需要大约 70 位的精度才能正确存储 20 位小数的数字。 IEEE754 格式的 long doublefloat96float128)具有 80 位或 106 位精度,两者都足以完成任务。

很遗憾,numpy.random.Generator.random 仅支持 float32float64

基于 mpmath.rand, the source of randomness is just the standard library random module, specifically random.getrandbits. You should be able to get reproducible results by calling the usual random.seed. Unfortunately, the state is global: there does not appear to be a mechanism to use individual random.Random 对象的当前 python 实现,例如,针对不同的线程。

请记住,您需要设置 working 精度,这可以在上下文管理器中完成:

random.seed(my_seed)
with mp.workdps(22):
    data = [mp.rand() for _ in range(my_size)]

如果您有一组作为模块导入的脚本,在主驱动程序中调用 random.seed(my_seed) 就足以初始化整个程序。

如果您在外部调用脚本,例如通过 ossubprocess,您需要在每个脚本中放置相同的行。此时使用 import guard 更安全,因此您可以在不考虑它的情况下以两种方式使用脚本:

if __name__ == '__main__':
    random.seed(my_seed)

一种天真的方法:您可以在必要的范围内创建随机字符串文字并将它们提供给 Decimal 构造函数:

import random
from decimal import Decimal,getcontext
getcontext().prec = 20

def rand_decimal():
    s = ''.join(random.choice('0123456789') for _ in range(20))
    s = random.choice(['-','']) + '0.' + s
    return Decimal(s)

for _ in range(10): print(rand_decimal())

典型输出:

-0.83346823024126032930
-0.84557526920081542182
-0.82525161638966954542
0.19433739638125145525
-0.21238635133910933910
0.53423291362045018461
0.01119989426218875072
-0.60199160675918881160
-0.53317266699396870741
-0.16609409040022211062