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

问题描述 投票:0回答:5

在 Cython

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

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()
的正确“标准化”数字? 编辑 另外,如果使用从 libc 调用
rand()
的 C 方法,如何设置随机种子(例如,根据当前时间播种)?

python random numpy cython
5个回答
14
投票

C 标准规定

rand
返回 0 到 RAND_MAX(含)范围内的
int
,因此将其除以 RAND_MAX(来自
stdlib.h
)是对其进行标准化的正确方法。实际上,RAND_MAX 几乎总是等于 MAX_INT,但不要依赖于此。

因为

rand
自 C89 以来一直是 ISO C 的一部分,因此保证它在任何地方都可用,但不保证其随机数的质量。不过,如果可移植性是您主要关心的问题,那么它是您的最佳选择,除非您愿意使用 Python 的
random
模块。

Python 的

sys.maxint
是完全不同的概念;它只是 Python 可以用“它自己的”int 类型表示的最大正数;较大的必须是多头。 Python 的 int 和 long 与 C 的没有特别相关。


4
投票

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)

我在研究你的除法方法是否产生足够的随机性时遇到了
这个想法

。我发现的来源提出了一个很好的观点,在我的例子中,我将随机数与两位数的小数进行比较,因此我实际上只需要 3 个小数点的精度。所以 INT_MAX 已经足够了。但是,看起来 drand48 节省了除法成本,因此可能值得使用。


3
投票

有什么理由不使用 python random() 吗?

生成 0 到 9 之间的随机整数


3
投票


0
投票
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

版本的值相同:

from libc.stdlib cimport rand, RAND_MAX cdef float scale = 1.0 / RAND_MAX cpdef float crandom(): return rand() * scale

© www.soinside.com 2019 - 2024. All rights reserved.