ksi*_*ndi 2 random multithreading cython
生成伪统一随机数([0,1中的双精度数])的最佳方法是:
3年前也有类似的文章,但是很多答案并不符合所有标准。例如,drand48特定于POSIX。
我知道的(但不确定)满足所有某些条件的唯一方法是:
from libc.stdlib cimport rand, RAND_MAX
random = rand() / (RAND_MAX + 1.0)
Run Code Online (Sandbox Code Playgroud)
注意@ogrisel 大约在3年前问了同样的问题。
编辑
调用rand不是线程安全的。感谢您指出@DavidW。
我认为最简单的方法是使用C ++ 11标准库,该库提供了不错的封装随机数生成器以及使用它们的方法。当然,这不是唯一的选择,并且您可以包装几乎所有合适的C / C ++库(一个不错的选择可能是使用numpy使用的任何库,因为它很可能已经安装了)。
我的一般建议是只包装所需的位,而不必理会完整的层次结构和所有可选的模板参数。举例来说,我已经展示了默认生成器之一,它被馈送到统一的float分布中。
# distutils: language = c++
# distutils: extra_compile_args = -std=c++11
cdef extern from "<random>" namespace "std":
cdef cppclass mt19937:
mt19937() # we need to define this constructor to stack allocate classes in Cython
mt19937(unsigned int seed) # not worrying about matching the exact int type for seed
cdef cppclass uniform_real_distribution[T]:
uniform_real_distribution()
uniform_real_distribution(T a, T b)
T operator()(mt19937 gen) # ignore the possibility of using other classes for "gen"
def test():
cdef:
mt19937 gen = mt19937(5)
uniform_real_distribution[double] dist = uniform_real_distribution[double](0.0,1.0)
return dist(gen)
Run Code Online (Sandbox Code Playgroud)
(-std=c++11开始时是针对GCC的。对于其他编译器,您可能需要进行调整。无论如何,默认情况下c ++ 11越来越多,因此可以将其删除)
参考您的标准:
mt19937对象内(每个线程应具有自己的mt19937)。编辑:关于使用discrete_distribution。
这有点困难,因为for的构造函数discrete_distribution不太容易包装(它们涉及迭代器)。我认为最简单的方法是通过C ++向量,因为对此的支持内置在Cython中,并且可以轻松地与Python列表进行相互转换。
# use Cython's built in wrapping of std::vector
from libcpp.vector cimport vector
cdef extern from "<random>" namespace "std":
# mt19937 as before
cdef cppclass discrete_distribution[T]:
discrete_distribution()
# The following constructor is really a more generic template class
# but tell Cython it only accepts vector iterators
discrete_distribution(vector.iterator first, vector.iterator last)
T operator()(mt19937 gen)
# an example function
def test2():
cdef:
mt19937 gen = mt19937(5)
vector[double] values = [1,3,3,1] # autoconvert vector from Python list
discrete_distribution[int] dd = discrete_distribution[int](values.begin(),values.end())
return dd(gen)
Run Code Online (Sandbox Code Playgroud)
显然,这比均匀分布要复杂得多,但是它并没有那么复杂(并且讨厌的位可能隐藏在Cython函数中)。
| 归档时间: |
|
| 查看次数: |
771 次 |
| 最近记录: |