Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
std::seed_seq::generate(3)    C++ Standard Libary   std::seed_seq::generate(3)

NAME
       std::seed_seq::generate - std::seed_seq::generate

Synopsis
	  template< class RandomIt >			  (since C++11)
	  void generate( RandomIt begin, RandomIt end );

	  Fills	 the range [begin, end)	with unsigned integer values i,	0  i <
       232
	  , based on the data originally provided in the constructor  of  this
       seed_seq. The
	  produced values are distributed over the entire 32-bit range even if
       the initial
	  values were strongly biased.

	  The following	algorithm is used (adapted from	the initialization se-
       quence of the
	  Mersenne Twister generator by	Makoto Matsumoto and Takuji Nishimura,
       incorporating
	  the improvements made	by Mutsuo Saito	in 2007)

	    * If begin == end, do nothing. Otherwise,

	    *  First,  set  each  element  of  the  output  range to the value
       0x8b8b8b8b

	    * Transform	the elements of	the output range according to the fol-
       lowing algorithm:

	  For k	= 0,..., m-1

	  where	m=max(s+1, n)
	  and n=end-begin
	  and s=v.size()
	  and v	is the private container holding the  values  originally  pro-
       vided by	the
	  constructor of this seed_seq object,

	   1. begin[k+p] += r1
	   2. begin[k+q] += r2
	   3. begin[k] = r2,

	  where	p=(n-t)/2
	  and q=p+t
	  and t=(n >= 623) ? 11	: (n >=	68) ? 7	: (n >=	39) ? 5	: (n >=	7) ? 3
       : (n - 1) / 2
	  and r1=1664525 * T(begin[k]^begin[k+p]^begin[k1])
	  and T(x) = x ^ (x >> 27)
	  and  r2=r1+s if k==0,	r2=r1 +	k%n + v[k-1] if	0<k<=s,	r2=r1 +	k%n if
       k>s.

	  For k	= m,..., m+n-1,

	   1. begin[k+p] ^= r3
	   2. begin[k+q] ^= r4
	   3. begin[k]=r4

	  where	r3 = 1566083941	* T(begin[k]+begin[k+p]+begin[k-1])
	  and r4=r3 - k%n

	  where	all calculations are performed modulo 232
	  and where the	indexing of the	output range (begin[x])	is taken  mod-
       ulo n.

Parameters
		       mutable random-access iterators whose
	  begin, end - std::iterator_traits<>::value_type is an	unsigned inte-
       ger type	suitable
		       for storing 32-bit values

Type requirements
	  -
	  RandomIt must	meet the requirements of LegacyRandomAccessIterator.

Return value
	  none,	the results are	written	to the [begin, end) range.

Exceptions
	  Only throws if the operations	on begin and end throw.

Example
       // Run this code

	#include <algorithm>
	#include <cassert>
	#include <cstdint>
	#include <iostream>
	#include <random>

	// Prototyping the main	part of	std::seed_seq...
	struct seed_seq	{
	    std::vector<std::uint32_t> v;

	    seed_seq(std::initializer_list<std::uint32_t> const	il) : v{il} {}

	    template <typename RandomIt>
	    void generate(RandomIt first, RandomIt last) {
		if (first == last)
		    return;
		//
		// Assuming v =	{1,2,3,4,5} and	distance(first,	last) == 10.
		//
		// Step	1: fill	with 0x8b8b8b8b
		//  seeds  =  {2341178251, 2341178251, 2341178251, 2341178251,
       2341178251,
		//	    2341178251,	 2341178251,  2341178251,  2341178251,
       2341178251 }
		//
		std::fill(first, last, 0x8b8b8b8b);
		//
		// Step	2:
		// n = 10, s = 5, t = 3, p = 3,	q = 6, m = 10
		//
		const std::uint32_t n =	last - first;
		const std::uint32_t s =	v.size();
		const std::uint32_t t =	(n < 7)	? (n - 1) / 2
				      :	(n < 39) ? 3
				      :	(n < 68)  ? 5
				      :	(n < 623)  ? 7
				      :	11;
		const std::uint32_t p =	(n - t)	/ 2;
		const std::uint32_t q =	p + t;
		const std::uint32_t m =	std::max(s + 1,	n);
		//
		// First iteration, k =	0; r1 =	1371501266, r2 = 1371501271
		//
		//  seeds  =  {1371501271, 2341178251, 2341178251, 3712679517,
       2341178251,
		//	    2341178251,	 3712679522,  2341178251,  2341178251,
       2341178251 }
		//
		// Iterations from k = 1 to k =	5 (r2 =	r1 + k%n + v[k-1])
		//
		//   r1	 =  2786190137,	 3204727651,  4173325571,  1979226628,
       401983366
		//  r2	=  2786190139,	3204727655,  4173325577,   1979226636,
       401983376
		//
		//  seeds  =  {3350727907, 3188173515, 3204727655, 4173325577,
       1979226636,
		//	     401983376,	 3591037797,  2811627722,  1652921976,
       2219536532 }
		//
		// Iterations from k = 6 to k =	9 (r2 =	r1 + k%n)
		//
		// r1 =	2718637909, 1378394210,	2297813071, 1608643617
		// r2 =	2718637915, 1378394217,	2297813079, 1608643626
		//
		//  seeds  =  {	434154821, 1191019290, 3237041891, 1256752498,
       4277039715,
		//	    2010627002,	 2718637915,  1378394217,  2297813079,
       1608643626 }
		//
		auto   begin_mod   =   [first,	 n](std::uint32_t  u)  ->  de-
       cltype(*first)& {
		    return first[u % n]; // i.e. begin[x] is taken modulo n
		};
		auto T = [](std::uint32_t x) { return x	^ (x >>	27); };

		for (std::uint32_t k = 0, r1, r2; k < m; ++k) {
		    r1 = 1664525 * T(begin_mod(k) ^ begin_mod(k	 +  p)	^  be-
       gin_mod(k - 1));
		    r2 = (k == 0) ? r1 + s
		       : (k <= s) ? r1 + k % n + v[k - 1]
		       :	    r1 + k % n;
		    begin_mod(k	+ p) +=	r1;
		    begin_mod(k	+ q) +=	r2;
		    begin_mod(k) = r2;
		}
		//
		// Step	3
		//  iterations	from  k	= 10 to	k = 19,	using ^= to modify the
       output
		//
		//  r1	=  1615303485,	3210438310,   893477041,   2884072672,
       1918321961,
		//   r2	  =  1615303485,  3210438309,  893477039,  2884072669,
       1918321957
		//
		// seeds = { 303093272,	 3210438309,   893477039,  2884072669,
       1918321957,
		//	     1117182731,  1772877958,  2669970405, 3182737656,
       4094066935 }
		//
		//  r1	=   423054846,	 46783064,   3904109085,   1534123446,
       1495905687
		//   r2	  =    423054841,  46783058,  3904109078,  1534123438,
       1495905678
		//
		// seeds = { 4204997637, 4246533866,  1856049002,  1129615051,
       690460811,
		//	      1075771511,    46783058, 3904109078, 1534123438,
       1495905678 }
		//
		for (std::uint32_t k = m, r3, r4; k < m	+ n; ++k) {
		    r3 = 1566083941 * T(begin_mod(k) +	begin_mod(k+p)	+  be-
       gin_mod(k-1));
		    r4 = r3 - k%n;
		    begin_mod(k+p) ^= r3;
		    begin_mod(k+q) ^= r4;
		    begin_mod(k) = r4;
		}
	    }
	};

	int main()
	{

	    const	   auto		 input	       =	 std::initial-
       izer_list<std::uint32_t>{1,2,3,4,5};
	    const auto output_size = 10;

	    // using std version of seed_seq
	    std::seed_seq seq(input);
	    std::vector<std::uint32_t> seeds(output_size);
	    seq.generate(seeds.begin(),	seeds.end());
	    for(const std::uint32_t n :	seeds) {
		std::cout << n << '\n';
	    }

	    // using custom version of seed_seq
	    seed_seq seq2(input);
	    std::vector<std::uint32_t> seeds2(output_size);
	    seq2.generate(seeds2.begin(), seeds2.end());

	    assert(seeds == seeds2);
	}

Output:
	4204997637
	4246533866
	1856049002
	1129615051
	690460811
	1075771511
	46783058
	3904109078
	1534123438
	1495905678

http://cppreference.com		  2022.07.31	    std::seed_seq::generate(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::seed_seq::generate&sektion=3&manpath=FreeBSD+Ports+15.0>

home | help