Правильный способ генерации случайных чисел в Cython? - программирование
Подтвердить что ты не робот

Правильный способ генерации случайных чисел в Cython?

Каков наиболее эффективный и переносимый способ генерации случайного случайного в [0,1] в Cython? Один из подходов состоит в использовании INT_MAX и rand() из библиотеки C:

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-подход вызова rand() из libc?

4b9b3361

Ответ 1

В стандарте C говорится, что rand возвращает int в диапазоне от 0 до RAND_MAX включительно, поэтому деление его на RAND_MAX (от stdlib.h) является правильным способом его нормализации. На практике RAND_MAX почти всегда будет равен MAX_INT, но не полагайтесь на это.

Поскольку rand является частью ISO C с момента его появления на C89, он гарантированно доступен везде, но никаких гарантий относительно качества его случайных чисел не предоставляется. Если переносимость - это ваша главная проблема, это ваш лучший вариант, если вы не хотите использовать модуль Python random.

Python sys.maxint - это совсем другое понятие; это просто наибольшее положительное число, которое Python может представлять в своем собственном типе int; более крупные должны быть длинными. Python ints и longs не имеют особого отношения к C.

Ответ 3

Я не уверен, что 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)

Я столкнулся с этой идеей, исследуя, сформировал ли ваш метод разделения достаточную случайность. Источник, который я нашел, делает хорошую точку зрения, что в моем случае я сравниваю случайное число с десятичной цифрой с двумя цифрами, поэтому мне действительно нужны только 3 десятичные точки точности. Поэтому INT_MAX более чем достаточно. Но, похоже, drand48 экономит стоимость деления, поэтому его можно было бы использовать.