我想在-1到1的范围内生成至少20位的种子随机浮点数。
import numpy as np
np.random.seed(2000)
np.random.uniform(low=-1, high=1, size=2)
这是我过去会做的,但我的能源部研究需要更精确。
我已经研究了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+小数点和可播种的随机浮点数?
一种朴素的方法:您可以在必要的范围内创建随机字符串字面量,并将它们提供给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
首先,您将需要~70位的精度来正确存储包含20位十进制数字的数字。IEEE754格式的long double
(float96
或float128
)具有80或106位的精度,这两个精度都足以满足任务。
遗憾的是,numpy.random.Generator.random
只支持float32
和float64
。
基于目前mpmath.rand
的python实现,随机性的来源只是标准库random
模块,具体来说是random.getrandbits
。通过调用通常的random.seed
,您应该能够获得可重复的结果。不幸的是,状态是全局的:似乎没有一种机制可以使用单独的random.Random
对象,例如,用于不同的线程。
请记住,您需要设置工作精度,这可以在上下文管理器中完成:
random.seed(my_seed)
with mp.workdps(22):
data = [mp.rand() for _ in range(my_size)]
如果你有一组脚本被作为模块导入,在你的主驱动程序中调用random.seed(my_seed)
就足以初始化整个程序。
如果你在外部调用脚本,例如通过os
或subprocess
,你会想在每个脚本中放置相同的行。此时使用导入保护更安全,因此您可以不用考虑就以两种方式使用脚本:
if __name__ == '__main__':
random.seed(my_seed)