29 Numerics library [numerics]

29.6 Random number generation [rand]

29.6.3 Random number engine class templates [rand.eng]

Каждый тип, созданный из шаблона класса, указанного в этом разделе, [rand.eng] удовлетворяет требованиям random number engine типа.

Если не указано иное, сложность каждой функции, указанной в этом разделе, [rand.eng] является постоянной.

Если не указано иное, ни одна функция, описанная в этом разделе, не [rand.eng] вызывает исключение.

Каждая функция, описанная в этом разделе, [rand.eng] которая имеет параметр функции q типа Sseq& для параметра типа шаблона с именем Sseq , отличным от типа, seed_­seq вызывает то, что и когда q.generate вызывает вызов throw.

Описания представлены в этом разделе [rand.eng] только для операций двигателя, которые не описаны, [rand.req.eng] или для операций, для которых имеется дополнительная семантическая информация. В частности, объявления для конструкторов копирования, для операторов присваивания копий, для операторов потоковой передачи и для операторов равенства и неравенства не показаны в резюме.

Каждый шаблон, указанный в этом разделе, [rand.eng] требует удержания одного или нескольких отношений, включающих значение (значения) не относящихся к типу параметров шаблона. Программа, реализующая любой из этих шаблонов, плохо сформирована, если какая-либо такая требуемая взаимосвязь не выполняется.

Для каждого механизма случайных чисел и для каждого адаптера механизма случайных чисел, X определенных в этом подпункте ([rand.eng]) и в подпункте [rand.adapt]:

  • если конструктор

    template <class Sseq> explicit X(Sseq& q);

    вызывается с типом Sseq , который не квалифицируется как начальная последовательность, тогда этот конструктор не должен участвовать в разрешении перегрузки;

  • если функция-член

    template <class Sseq> void seed(Sseq& q);

    вызывается с типом Sseq , который не квалифицируется как начальная последовательность, то эта функция не должна участвовать в разрешении перегрузки.

Степень, в которой реализация определяет, что тип не может быть начальной последовательностью, не указана, за исключением того, что, как минимум, тип не должен квалифицироваться как начальная последовательность, если он неявно конвертируется в X​::​result_­type.

29.6.3.1 Class template linear_­congruential_­engine [rand.eng.lcong]

Механизм linear_­congruential_­engine случайных чисел производит беззнаковые целые случайные числа. Состояние из объекта имеет размер и состоит из одного целого числа. Алгоритм перехода представляет собой модульную линейную функцию формы ; алгоритм генерации есть . xi linear_­congruential_­engine x 1TA(xi)=(axi+c)modm GA(xi)=xi+1

template<class UIntType, UIntType a, UIntType c, UIntType m>
  class linear_congruential_engine {
  public:
    // types
    using result_type = UIntType;

    // engine characteristics
    static constexpr result_type multiplier = a;
    static constexpr result_type increment = c;
    static constexpr result_type modulus = m;
    static constexpr result_type min() { return c == 0u ? 1u: 0u; }
    static constexpr result_type max() { return m - 1u; }
    static constexpr result_type default_seed = 1u;

    // constructors and seeding functions
    explicit linear_congruential_engine(result_type s = default_seed);
    template<class Sseq> explicit linear_congruential_engine(Sseq& q);
    void seed(result_type s = default_seed);
    template<class Sseq> void seed(Sseq& q);

    // generating functions
    result_type operator()();
    void discard(unsigned long long z);
  };

Если параметр шаблона m равен 0, модуль, m используемый в этом разделе, равен плюсу . [ не обязательно представлять как значение типа . ] [rand.eng.lcong] numeric_­limits<result_­type>​::​max() 1Note: m result_­typeend note

Если параметр шаблона m не равен 0, должны выполняться следующие отношения: a < m и c < m.

Текстовое представление состоит из значения xi.

explicit linear_congruential_engine(result_type s = default_seed);

Effects: Создает linear_­congruential_­engine объект. Если cmodm есть 0 и smodm есть 0, устанавливает состояние двигателя в 1, в противном случае устанавливает состояние двигателя в smodm.

template<class Sseq> explicit linear_congruential_engine(Sseq& q);

Effects: Создает linear_­congruential_­engine объект. С k=log2m32 и a массивом (или эквивалентом) длины k+3вызывает, q.generate(a+0, a+k+3) а затем вычисляет S=(k1j=0aj+3232j)modm. Если cmodm есть 0 и S есть 0, устанавливает состояние двигателя в 1, иначе устанавливает состояние двигателя в S.

29.6.3.2 Class template mersenne_­twister_­engine [rand.eng.mers]

Механизм mersenne_­twister_­engine случайных чисел270 производит беззнаковые целые случайные числа в закрытом интервале [0,2w1]. Состояние из объекта имеет размер и состоит из последовательности из значений типа поставляемого ; все применяемые индексы следует брать по модулю .xi mersenne_­twister_­engine x n X n x X n

Алгоритм перехода использует сдвиговый регистр с обобщенной обратной связью, определяемый значениями сдвига и , значением поворота и условной xor-маской . Чтобы улучшить однородность результата, биты необработанного регистра сдвига дополнительно (т. Е. Скремблируются) в соответствии с матрицей битового скремблирования, определенной значениями и . n m r a tempered u,d,s,b,t,c,

Переход между состояниями выполняется следующим образом:

  1. a)Соедините верхние wr биты Xin с младшими r битами, Xi+1n чтобы получить беззнаковое целое число Y.

  2. b)С α=a(Ybitand1), установите Xi на Xi+mnxor(Yrshift1)xorα.

Последовательность X инициализируется с помощью множителя инициализации f.

Алгоритм генерации определяет беззнаковые целочисленные значения следующим образом, а затем выдает в качестве своего результата: z1,z2,z3,z4 z4

  1. a)Пусть z1=Xixor((Xirshiftu)bitandd).

  2. b)Пусть z2=z1xor((z1lshiftws)bitandb).

  3. c)Пусть z3=z2xor((z2lshiftwt)bitandc).

  4. d)Пусть z4=z3xor(z3rshift).

template<class UIntType, size_t w, size_t n, size_t m, size_t r,
         UIntType a, size_t u, UIntType d, size_t s,
         UIntType b, size_t t,
         UIntType c, size_t l, UIntType f>
  class mersenne_twister_engine {
  public:
    // types
    using result_type = UIntType;

    // engine characteristics
    static constexpr size_t word_size = w;
    static constexpr size_t state_size = n;
    static constexpr size_t shift_size = m;
    static constexpr size_t mask_bits = r;
    static constexpr UIntType xor_mask = a;
    static constexpr size_t tempering_u = u;
    static constexpr UIntType tempering_d = d;
    static constexpr size_t tempering_s = s;
    static constexpr UIntType tempering_b = b;
    static constexpr size_t tempering_t = t;
    static constexpr UIntType tempering_c = c;
    static constexpr size_t tempering_l = l;
    static constexpr UIntType initialization_multiplier = f;
    static constexpr result_type min() { return 0; }
    static constexpr result_type max() { return  2w1; }
    static constexpr result_type default_seed = 5489u;

    // constructors and seeding functions
    explicit mersenne_twister_engine(result_type value = default_seed);
    template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
    void seed(result_type value = default_seed);
    template<class Sseq> void seed(Sseq& q);

    // generating functions
    result_type operator()();
    void discard(unsigned long long z);
  };

Следующие соотношения должны занимать: 0 < m, m <= n, 2u < w, r <= w, u <= w, s <= w, t <= w, l <= w, w <= numeric_­limits<UIntType>​::​digits, a <= (1u<<w) - 1u, b <= (1u<<w) - 1u, c <= (1u<<w) - 1u, d <= (1u<<w) - 1u, и f <= (1u<<w) - 1u.

Текстовое представление о xi состоит из значений Xin,,Xi1, в таком порядке.

explicit mersenne_twister_engine(result_type value = default_seed);

Effects: Создает mersenne_­twister_­engine объект. Устанавливается Xn на valuemod2w. Затем итеративно для i=1n,,1, наборы Xi для

[f(Xi1xor(Xi1rshift(w2)))+imodn]mod2w.

Complexity: O(n).

template<class Sseq> explicit mersenne_twister_engine(Sseq& q);

Effects: Создает mersenne_­twister_­engine объект. With k=w/32 и a массив (или эквивалент) длины nkвызывает, q.generate(a+0, a+nk) а затем, итеративно для i=n,,1, устанавливает Xi значение (k1j=0ak(i+n)+j232j)mod2w. Наконец, если наиболее значимые wr биты Xn равны нуль, и если каждый из других в результате чего Xi это 0, изменяется Xn с 2w1.

Название этого механизма частично относится к свойству его периода: для правильно выбранных значений параметров период тесно связан с большим простым числом Мерсенна.

29.6.3.3 Class template subtract_­with_­carry_­engine [rand.eng.sub]

Механизм subtract_­with_­carry_­engine случайных чисел производит беззнаковые целые случайные числа.

Состояние из объекта имеет размера , и состоит из последовательности из целочисленных значений ; все применяемые индексы следует брать по модулю . Состояние дополнительно состоит из целого числа (известного как ) , значение которого равно или . xi subtract_­with_­carry_­engine xO(r) X r 0Xi<m=2w X r xi c carry 0 1

Переход между состояниями выполняется следующим образом:

  1. a)Пусть Y=XisXirc.

  2. b)Установите Xi на y=Ymodm. Установите c в 1, если Y<0, в противном случае установите c в 0.

[ Note: Этот алгоритм соответствует модульной линейной функции вида TA(xi)=(axi)modb, где b имеет вид mrms+1 и a=b(b1)/m. ]end note

Алгоритм генерации задается формулой , где - значение, полученное в результате улучшения состояния двигателя, как описано выше.GA(xi)=y y

template<class UIntType, size_t w, size_t s, size_t r>
  class subtract_with_carry_engine {
  public:
    // types
    using result_type = UIntType;

    // engine characteristics
    static constexpr size_t word_size = w;
    static constexpr size_t short_lag = s;
    static constexpr size_t long_lag = r;
    static constexpr result_type min() { return 0; }
    static constexpr result_type max() { return m1; }
    static constexpr result_type default_seed = 19780503u;

    // constructors and seeding functions
    explicit subtract_with_carry_engine(result_type value = default_seed);
    template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
    void seed(result_type value = default_seed);
    template<class Sseq> void seed(Sseq& q);

    // generating functions
    result_type operator()();
    void discard(unsigned long long z);
  };

Следующие соотношения должны проводить: 0u < s, s < r, 0 < w, и w <= numeric_­limits<UIntType>​::​digits.

Текстовое представление состоит из значений в указанном порядке, за которыми следует . Xir,,Xi1 c

explicit subtract_with_carry_engine(result_type value = default_seed);

Effects: Создает subtract_­with_­carry_­engine объект. Устанавливает значения Xr,,X1в указанном ниже порядке в указанном ниже порядке. Если X1 есть, то 0устанавливается c в 1; в противном случае устанавливается c на 0.

Для того, чтобы установить значение Xk, первые построить e, А linear_­congruential_­engine объект, как если бы по следующему определению:

linear_congruential_engine<result_type,
                          40014u,0u,2147483563u> e(value == 0u ? default_seed : value);

Затем, чтобы установить каждый Xk, получить новые значения z0,,zn1 из n=w/32 последовательных вызовов e взятого по модулю 232. Установите Xk на (n1j=0zj232j)modm.

Complexity: Собственно nr заклинания e.

template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);

Effects: Создает subtract_­with_­carry_­engine объект. With k=w/32 и a массив (или эквивалент) длины rkвызывает, q.generate(a+0, a+rk) а затем, итеративно для i=r,,1, устанавливает Xi значение (k1j=0ak(i+r)+j232j)modm. Если X1 есть, то 0устанавливается c в 1; в противном случае устанавливается c на 0.