Random generators and variators
API for creating random generators and variators
Linear Congruential Generator
See w:Linear Congruential Generator
Uses MMIX constants, but tunable.
Unlike libc generator (that is most likely LCG too), non-singleton, so it
provides independent streams of pseudo-random numbers.
libc (default) random generator
Uses srand()/rand() functions from standard C library
Sequental generator
Uses API of random generators, but not really random generator.
Generates sequence with start value rg_seed and in interval [0; ULLONG_MAX)
Erlang distribution
Params:
-
shape (int)
-
rate (double)
Exponential distribution
See w:Exponential distribution
Params:
- rate (double)
Normal distribution
Uses Kinderman and Monahan method
Params:
-
mean (double) - mean value
- stddev (double) - standard deviation
Uniform distribution
Params:
-
min (double)
-
max (double)
Variables
rg_libc_class, rg_seq_class, rg_devrandom_class, rg_lcg_class
Random generators
TSLOADAPI randgen_class_t rg_libc_class TSLOADAPI randgen_class_t rg_seq_class TSLOADAPI randgen_class_t rg_lcg_class TSLOADAPI randgen_class_t rg_devrandom_class
Constants
RV_PARAM_OK, RV_INVALID_PARAM_NAME, RV_INVALID_PARAM_VALUE
Error codes returned by rv_set_int/rv_set_double
#define RV_PARAM_OK 0 #define RV_INVALID_PARAM_NAME -1 #define RV_INVALID_PARAM_VALUE -2
RV_PARAM_DOUBLE, RV_PARAM_NULL, RV_PARAM_INT
Random variator parameter types
#define RV_PARAM_NULL 0 #define RV_PARAM_INT 1 #define RV_PARAM_DOUBLE 2
Functions
rg_destroy, rg_create
public
LIBEXPORT randgen_t* rg_create(randgen_class_t* class, uint64_t seed) LIBEXPORT void rg_destroy(randgen_t* rg)
rg_generate_int
public
Generates integer with uniform distribution in range
STATIC_INLINE uint64_t rg_generate_int(randgen_t* rg)
rg_generate_double
public
Generates double with uniform distribution in range
LIBEXPORT double rg_generate_double(randgen_t* rg)
rg_init_dummy, rg_destroy_dummy
public
LIBEXPORT int rg_init_dummy(randgen_t* rg) LIBEXPORT void rg_destroy_dummy(randgen_t* rg)
randgen_unregister, randgen_register
public
LIBEXPORT int randgen_register(module_t* mod, randgen_class_t* class) LIBEXPORT int randgen_unregister(module_t* mod, randgen_class_t* class)
rv_destroy, rv_create
public
LIBEXPORT randvar_t* rv_create(randvar_class_t* class, randgen_t* rg) LIBEXPORT void rv_destroy(randvar_t* rv)
rv_set_int
public
STATIC_INLINE int rv_set_int(randvar_t* rv, const char* name, long value)
rv_set_double
public
STATIC_INLINE int rv_set_double(randvar_t* rv, const char* name, double value)
rv_variate_double
public
STATIC_INLINE double rv_variate_double(randvar_t* rv)
rv_destroy_dummy, rv_set_int_dummy, rv_init_dummy, rv_set_double_dummy
public
LIBEXPORT int rv_init_dummy(randvar_t* rv) LIBEXPORT void rv_destroy_dummy(randvar_t* rv) LIBEXPORT int rv_set_int_dummy(randvar_t* rv, const char* name, long value) LIBEXPORT int rv_set_double_dummy(randvar_t* rv, const char* name, double value)
randvar_register, randvar_unregister
public
LIBEXPORT int randvar_register(module_t* mod, randvar_class_t* class) LIBEXPORT int randvar_unregister(module_t* mod, randvar_class_t* class)
randgen_fini, randgen_init
public
LIBEXPORT int randgen_init(void) LIBEXPORT void randgen_fini(void)
tsobj_randgen_class_format, tsobj_randvar_class_format
public
LIBEXPORT tsobj_node_t* tsobj_randgen_class_format(randgen_class_t* rg_class) LIBEXPORT tsobj_node_t* tsobj_randvar_class_format(randvar_class_t* rv_class)
tsobj_randvar_proc, tsobj_randgen_proc
public
LIBEXPORT randgen_t* tsobj_randgen_proc(tsobj_node_t* node) LIBEXPORT randvar_t* tsobj_randvar_proc(tsobj_node_t* node, randgen_t* rg)
Types
typedef struct randgen
typedef struct randgen { struct randgen_class* rg_class; uint64_t rg_seed; void* rg_private; } randgen_t;
typedef struct randgen_class
Random generator class.
To create new generator class, initialize head members with RG_CLASS_HEAD
and set pointers to functions:
randgen_class_t rg_my_class = { RG_CLASS_HEAD("my", B_FALSE, max), rg_init_my, rg_destroy_my, rg_generate_int };
Note that TSLoad is not a cryptographic software, so predictability of PRNGs is not
a concern. It even have sequental generator that generates numbers as N+1 where
N is last value.
Each random generated value is uint64_t. Real representation is irrelevant, i.e. for
/dev/urandom generator it is just a sequence of 8 bytes consequently read from device.
All conversion/limiting is done on a consumer side.
Random genrators should have uniform distribution in interval 0, rg_class->rg_max)
To apply different distribution, use random variators.
from TSLoad Core (libtsload) this field is set NULL
MEMBERS
-
rg_class_name - name of class (used in configs)
-
rg_is_singleton - is random generator is signleton (relies on global state)
-
rg_ref_count - reference count (for singleton)
-
rg_object - instance (for singleton)
-
rg_max - maximum integer that could be generated by this PRNG, i.e. LLONG_MAX
-
rg_next - next class in hashtable
-
rg_module - external module that implements this PRNG, for embedded generators
-
rg_init - function that initializes PRNG internal state
-
rg_destroy - function that frees PRNG internal state resources
-
rg_generate_int - generate next random number
typedef struct randgen_class { AUTOSTRING char* rg_class_name; boolean_t rg_is_singleton; atomic_t rg_ref_count; randgen_t* rg_object; uint64_t rg_max; struct randgen_class* rg_next; module_t* rg_module; int (*rg_init)(randgen_t* rg); void (*rg_destroy)(randgen_t* rg); uint64_t (*rg_generate_int)(randgen_t* rg); } randgen_class_t;
typedef struct randvar
typedef struct randvar { randgen_t* rv_generator; struct randvar_class* rv_class; void* rv_private; } randvar_t;
typedef struct randvar_class
Random variator class
Random variators are not generating numbers. They take it from upper-level
generator and modify it so probability funciton will conform desired distribution.
Random variators may have parameters of distribution settable via rv_set_int() and
rv_set_double() and described in rv_params (and of course in documentation).
Unlike random generators, variators work with double-precision floating point numbers
(double
type) distributed in
Head members are initialized with RV_CLASS_HEAD()
MEMBERS
-
rv_class_name - name of random variator class (for configs)
-
rv_next - next rv class in hashmap
-
rv_module - same as rg_module in randgen_class_t
-
rv_params - array of parameter descriptions
-
rv_init - function that initializes internal state of variator
-
rv_destroy - function that frees its internal state
-
rv_set_int - function that sets integer parameter
-
rv_set_double - function that sets double parameter
-
rv_variate_double - function that gets random-generated value u, and returns variated value
typedef struct randvar_class { AUTOSTRING char* rv_class_name; struct randvar_class* rv_next; module_t* rv_module; struct tsload_param* rv_params; int (*rv_init)(randvar_t* rv); void (*rv_destroy)(randvar_t* rv); int (*rv_set_int)(randvar_t* rv, const char* name, long value); int (*rv_set_double)(randvar_t* rv, const char* name, double value); double (*rv_variate_double)(randvar_t* rv, double u); } randvar_class_t;