python 在Cython中生成随机数的正确方法?

elcex8rz  于 2022-12-25  发布在  Python
关注(0)|答案(5)|浏览(402)

在Cython的[0,1]中生成随机数的最有效和可移植的方法是什么?一种方法是使用C库中的INT_MAXrand()

from libc.stdlib cimport rand
cdef extern from "limits.h":
    int INT_MAX
cdef float randnum = rand() / float(INT_MAX)

这样使用INT_MAX可以吗?我注意到它和你从Python的max int中得到的常量有很大的不同:

import sys
print INT_MAX
print sys.maxint

产量:

2147483647  (C max int)
9223372036854775807  (python max int)

哪个是rand()的正确“标准化”数?EDIT此外,如果使用C方法从libc调用rand(),如何设置随机种子(例如,基于当前时间播种)?

sf6xfgos

sf6xfgos1#

C标准规定rand返回0到兰德_MAX范围内的int,因此将其除以RAND_MAX(来自stdlib.h)是将其归一化的正确方法。实际上,RAND_MAX几乎总是等于MAX_INT,但不要依赖于此。
因为rand从C89开始就是ISO C的一部分,所以可以保证它在任何地方都可用,但是不能保证它的随机数的质量,如果移植性是你主要关心的问题,那么它是你最好的选择,除非你愿意使用Python的random模块。
Python的sys.maxint是一个完全不同的概念;它是Python在自己的int类型中所能表示的最大正数较大的必须是长整型,Python的整型和长整型与C语言没有特别的关系。

axzmvihb

axzmvihb2#

我不确定drand是否是一个新的添加,但它似乎做正是你想要的,同时避免昂贵的司。

cdef extern from "stdlib.h":
    double drand48()
    void srand48(long int seedval)

cdef extern from "time.h":
    long int time(int)

# srand48(time(0))
srand48(100)
# TODO: this is a seed to reproduce bugs, put to line of code above for
# production
drand48() #This gives a float in range [0,1)

我在研究你的除法是否能产生足够的随机性时偶然发现了this idea。我发现的源代码很好地说明了我的情况,我将随机数与两位数的小数进行比较,所以我只需要3个小数点的精度。所以INT_MAX是绰绰有余的。但是,drand48似乎节省了除法的成本,所以可能值得使用。

q1qsirdb

q1qsirdb3#

'c' stdlib兰德()返回0到RAND_MAX之间的数字,通常为32767。
有什么理由不使用python random()呢?
Generate random integers between 0 and 9

wswtfjt7

wswtfjt74#

以上所有答案都是正确的,但是我想补充一点,这花了我太长时间才理解。C兰德()函数不是线程安全的。因此,如果你在没有gil的情况下并行运行cython,标准的C rand()函数在试图处理所有内核调用时有可能导致巨大的速度下降。只是一个警告。

drnojrws

drnojrws5#

如下所示,我认为没有理由不喜欢python random.random()

import numpy as np
from ext.random import random as rd
%timeit rd()
48.6 ns ± 0.396 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

np.unique([rd() for _ in range(10000000)]).size
Out[5]: 32768

from random import random as rd_python
%timeit rd_python()
33.2 ns ± 0.213 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

np.unique([rd_python() for _ in range(10000000)]).size
Out[8]: 10000000

对于cython版本:

from libc.stdlib cimport rand, RAND_MAX

cpdef float random():
    return float(rand()) / RAND_MAX

相关问题