Program Listing for File RandomGenerators.h
↰ Return to documentation for file (ADS/numeric/RandomGenerators.h)
/*--------------------------------------------------------------------------*/
/*------------------------ File RandomGenerators.h -------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*----------------------------- DEFINITIONS --------------------------------*/
/*--------------------------------------------------------------------------*/
#ifndef __ADS_RandomGenerators
#define __ADS_RandomGenerators
/* self-identification: #endif constant */
/*--------------------------------------------------------------------------*/
/*------------------------------ INCLUDES ----------------------------------*/
/*--------------------------------------------------------------------------*/
#include "ADS/Contract.h"
#include "ADS/dictionary/RandomHashing.h"
#include "ADS/numeric/NumberTheory.h"
#include <array>
#include <bit>
#include <cmath>
#include <concepts>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <limits>
#include <utility>
#include <vector>
/*--------------------------------------------------------------------------*/
/*--------------------------- NAMESPACE ------------------------------------*/
/*--------------------------------------------------------------------------*/
#if defined( __GNUC__ ) || defined( __clang__ )
#define ADS_RNG_INLINE inline __attribute__(( always_inline ))
#elif defined( _MSC_VER )
#define ADS_RNG_INLINE __forceinline
#else
#define ADS_RNG_INLINE inline
#endif
namespace ADS {
template< class G >
concept FullWordGenerator =
std::uniform_random_bit_generator< std::remove_reference_t< G > > &&
std::same_as< typename std::remove_reference_t< G >::result_type ,
std::uint64_t > &&
( std::remove_reference_t< G >::min() == 0 ) &&
( std::remove_reference_t< G >::max() ==
std::numeric_limits< std::uint64_t >::max() );
/*--------------------------------------------------------------------------*/
/*--------------------------- CLASS Xoshiro256 -----------------------------*/
/*--------------------------------------------------------------------------*/
template< bool StarStar >
class Xoshiro256T {
public:
using result_type = std::uint64_t;
explicit constexpr Xoshiro256T( std::uint64_t seed = 1 );
constexpr std::uint64_t operator()( void );
constexpr void jump( void );
static constexpr std::uint64_t min( void ) { return( 0 ); }
static constexpr std::uint64_t max( void ) {
return( std::numeric_limits< std::uint64_t >::max() );
}
bool operator==( const Xoshiro256T & ) const = default;
private:
std::uint64_t f_s[ 4 ];
}; // end( class Xoshiro256T )
using Xoshiro256 = Xoshiro256T< false >;
using Xoshiro256StarStar = Xoshiro256T< true >;
/*--------------------------------------------------------------------------*/
/*----------------------------- CLASS WyRand -------------------------------*/
/*--------------------------------------------------------------------------*/
class WyRand {
public:
using result_type = std::uint64_t;
explicit constexpr WyRand( std::uint64_t seed = 1 ) : f_s( seed ) {}
constexpr std::uint64_t operator()( void );
static constexpr std::uint64_t min( void ) { return( 0 ); }
static constexpr std::uint64_t max( void ) {
return( std::numeric_limits< std::uint64_t >::max() );
}
bool operator==( const WyRand & ) const = default;
private:
std::uint64_t f_s;
}; // end( class WyRand )
/*--------------------------------------------------------------------------*/
/*----------------------------- CLASS PhiloxT ------------------------------*/
/*--------------------------------------------------------------------------*/
template< class W >
class PhiloxT {
static_assert( std::same_as< W , std::uint32_t > ||
std::same_as< W , std::uint64_t > ,
"words of 32 or 64 bits" );
public:
using result_type = W;
using Block = std::array< W , 4 >;
using Key = std::array< W , 2 >;
static constexpr W default_seed = 20111115u;
explicit constexpr PhiloxT( W seed = default_seed );
constexpr W operator()( void );
constexpr void discard( unsigned long long z );
constexpr void setCounter( const Block & c );
static constexpr Block block( Block c , Key k );
static constexpr W min( void ) { return( 0 ); }
static constexpr W max( void ) { return( std::numeric_limits< W >::max() ); }
bool operator==( const PhiloxT & ) const = default;
private:
static constexpr unsigned lanes = 2;
constexpr void refill( void );
Key f_key;
Block f_ctr{};
W f_buf[ 4 * lanes ] = {};
unsigned f_at = 4 * lanes;
}; // end( class PhiloxT )
using Philox4x32 = PhiloxT< std::uint32_t >;
using Philox4x64 = PhiloxT< std::uint64_t >;
/*--------------------------------------------------------------------------*/
/*--------------------------- CLASS AliasTable -----------------------------*/
/*--------------------------------------------------------------------------*/
class AliasTable {
public:
explicit AliasTable( const std::vector< double > & w );
[[nodiscard]] std::size_t size( void ) const { return( f_T.size() ); }
template< FullWordGenerator G >
std::size_t operator()( G && g ) const;
[[nodiscard]] double probability( std::size_t i ) const;
private:
struct Entry {
std::uint64_t keep;
std::uint32_t alias;
};
std::vector< Entry > f_T;
}; // end( class AliasTable )
/*--------------------------------------------------------------------------*/
/*------------------------------ FUNCTIONS ---------------------------------*/
/*--------------------------------------------------------------------------*/
template< FullWordGenerator G >
std::uint64_t uniformBelow( G && g , std::uint64_t s );
template< FullWordGenerator G >
double uniformReal( G && g );
template< FullWordGenerator G >
ADS_RNG_INLINE double normalZiggurat( G && g );
template< FullWordGenerator G >
ADS_RNG_INLINE double exponentialZiggurat( G && g );
template< std::random_access_iterator I , FullWordGenerator G >
void shuffleFast( I first , I last , G && g );
/*--------------------------------------------------------------------------*/
} // end( namespace ADS )
/*--------------------------------------------------------------------------*/
/*-------------------------- IMPLEMENTATION --------------------------------*/
/*--------------------------------------------------------------------------*/
#include "ADS/numeric/impl/RandomGenerators.tpp"
/*--------------------------------------------------------------------------*/
#endif /* RandomGenerators.h included */
/*--------------------------------------------------------------------------*/
/*----------------------- End File RandomGenerators.h ----------------------*/
/*--------------------------------------------------------------------------*/