From 50da396d04714a18fa087ebbd1f2316958dbd6bd Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 21 Jan 2021 08:26:54 +0100 Subject: Reverted namings: crand to crandom, and copt to coption. --- docs/copt_api.md | 85 --------------------------- docs/coption_api.md | 85 +++++++++++++++++++++++++++ docs/cpque_api.md | 2 +- docs/crand_api.md | 165 ---------------------------------------------------- docs/crandom_api.md | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 251 insertions(+), 251 deletions(-) delete mode 100644 docs/copt_api.md create mode 100644 docs/coption_api.md delete mode 100644 docs/crand_api.md create mode 100644 docs/crandom_api.md (limited to 'docs') diff --git a/docs/copt_api.md b/docs/copt_api.md deleted file mode 100644 index df49f66d..00000000 --- a/docs/copt_api.md +++ /dev/null @@ -1,85 +0,0 @@ -# STC Module [copt](../stc/copt.h): Command line argument parsing - -This describes the API of the *copt_get()* function for command line argument parsing. -See [getopt_long](https://www.freebsd.org/cgi/man.cgi?getopt_long(3)) for a similar posix function. - -## Types - -```c -enum { - copt_no_argument = 0, - copt_required_argument = 1, - copt_optional_argument = 2 -}; -typedef struct { - int ind; /* equivalent to optind */ - int opt; /* equivalent to optopt */ - const char *arg; /* equivalent to optarg */ - const char *faulty; /* points to the faulty option, if any */ - int longindex; /* index of long option; or -1 if short */ - ... -} copt_t; - -typedef struct { - const char *name; - int has_arg; - int val; -} copt_long_t; - -const copt_t copt_inits; -``` - -## Methods - -```c -copt_t copt_init(void); -int copt_get(copt_t *opt, int argc, char *argv[], - const char *shortopts, const copt_long_t *longopts); -``` - -## Example - -```c -#include -#include "stc/copt.h" - -int main(int argc, char *argv[]) { - static copt_long_t long_options[] = { - {"verbose", copt_no_argument, 'V'}, - {"help", copt_no_argument, 'H'}, - {"add", copt_no_argument, 'a'}, - {"append", copt_no_argument, 'b'}, - {"delete", copt_required_argument, 'd'}, - {"create", copt_required_argument, 'c'}, - {"file", copt_required_argument, 'f'}, - {NULL} - }; - copt_t opt = copt_inits; - int c; - while ((c = copt_get(&opt, argc, argv, ":if:lr", long_options)) != -1) { - switch (c) { - case 'V': case 'H': - case 'a': case 'b': - case 'd': case 'c': - case 'i': case 'l': - case 'r': - printf("option: %c\n", c); - break; - case 'f': - printf("filename: %s\n", opt.arg); - break; - case ':': - printf("option %s needs a value\n", opt.faulty); - break; - case '?': - printf("unknown option: %s\n", opt.faulty); - break; - } - } - - for (; opt.ind < argc; ++opt.ind) { - printf("extra arguments: %s\n", argv[opt.ind]); - } - return 0; -} -``` diff --git a/docs/coption_api.md b/docs/coption_api.md new file mode 100644 index 00000000..66038b38 --- /dev/null +++ b/docs/coption_api.md @@ -0,0 +1,85 @@ +# STC Module [copt](../stc/coption.h): Command line argument parsing + +This describes the API of the *coption_get()* function for command line argument parsing. +See [getopt_long](https://www.freebsd.org/cgi/man.cgi?getopt_long(3)) for a similar posix function. + +## Types + +```c +enum { + copt_no_argument = 0, + copt_required_argument = 1, + copt_optional_argument = 2 +}; +typedef struct { + int ind; /* equivalent to posix optind */ + int opt; /* equivalent to posix optopt */ + const char *arg; /* equivalent to posix optarg */ + const char *faulty; /* points to the faulty option, if any */ + int longindex; /* index of long option; or -1 if short */ + ... +} coption; + +typedef struct { + const char *name; + int has_arg; + int val; +} coption_long; + +const coption coption_inits; +``` + +## Methods + +```c +coption coption_init(void); +int coption_get(coption *opt, int argc, char *argv[], + const char *shortopts, const coption_long *longopts); +``` + +## Example + +```c +#include +#include "stc/coption.h" + +int main(int argc, char *argv[]) { + static coption_long long_options[] = { + {"verbose", copt_no_argument, 'V'}, + {"help", copt_no_argument, 'H'}, + {"add", copt_no_argument, 'a'}, + {"append", copt_no_argument, 'b'}, + {"delete", copt_required_argument, 'd'}, + {"create", copt_required_argument, 'c'}, + {"file", copt_required_argument, 'f'}, + {NULL} + }; + coption opt = coption_init(); + int c; + while ((c = coption_get(&opt, argc, argv, ":if:lr", long_options)) != -1) { + switch (c) { + case 'V': case 'H': + case 'a': case 'b': + case 'd': case 'c': + case 'i': case 'l': + case 'r': + printf("option: %c\n", c); + break; + case 'f': + printf("filename: %s\n", opt.arg); + break; + case ':': + printf("option %s needs a value\n", opt.faulty); + break; + case '?': + printf("unknown option: %s\n", opt.faulty); + break; + } + } + + for (; opt.ind < argc; ++opt.ind) { + printf("extra arguments: %s\n", argv[opt.ind]); + } + return 0; +} +``` diff --git a/docs/cpque_api.md b/docs/cpque_api.md index 59203a63..080d580e 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -60,7 +60,7 @@ cpque_X_value_t cpque_X_value_clone(cpque_X_value_t val); ```c #include #include "stc/cpque.h" -#include "stc/crand.h" +#include "stc/crandom.h" using_cvec(i, int64_t); using_cpque(i, cvec_i, >); // adaptor type, '>' = min-heap diff --git a/docs/crand_api.md b/docs/crand_api.md deleted file mode 100644 index 995c5fa0..00000000 --- a/docs/crand_api.md +++ /dev/null @@ -1,165 +0,0 @@ -# STC Module [crand](../stc/crand.h): Pseudo Random Number Generators -![Random](pics/random.jpg) - -This describes the API of module **crand**. It contains **stc64**, a *64-bit PRNG*, and can generate -bounded uniform and normal distributed random numbers. See [random](https://en.cppreference.com/w/cpp/header/random) -for similar c++ functionality. - -**stc64** is an extremely fast PRNG by Tyge Løvset, suited for parallel usage. It features a -Weyl-sequence as part of the state. It is faster than *sfc64*, *wyhash64*, *pcg64*, and *xoshiro256\*\** -on common platforms. It does not require fast multiplication or 128-bit integer operations. It has a -256 bit state, but updates only 192 bit per generated number. - -There is no *jump function*, but by incrementing the Weyl-increment by 2, it starts a new -unique 2^64 *minimum* length period. Note that for each Weyl-increment (state[3]), the period -length is about 2^126 with a high probability. For a single thread, a minimum period of 2^127 -is generated when the Weyl-increment is incremented by 2 every 2^64 output. - -**stc64** passes *PractRand*, tested up to 8TB output, Vigna's Hamming weight test, and simple -correlation tests, i.e. *n* interleaved streams with only one-bit differences in initial state. - -See the PRNG shootout by Vigna: http://prng.di.unimi.it and the debate between the authors of -xoshiro and pcg (Vigna/O'Neill) PRNGs: https://www.pcg-random.org/posts/on-vignas-pcg-critique.html - -## Types - -| Name | Type definition | Used to represent... | -|:-------------------|:------------------------------------------|:-----------------------------| -| `stc64_t` | `struct {uint64_t state[4];}` | The PRNG engine type | -| `stc64_uniform_t` | `struct {int64_t lower; uint64_t range;}` | Integer uniform distribution | -| `stc64_uniformf_t` | `struct {double lower, range;}` | Real number uniform distr. | -| `stc64_normalf_t` | `struct {double mean, stddev;}` | Normal distribution type | - -## Header file - -All cstr definitions and prototypes may be included in your C source file by including a single header file. -```c -#include "stc/crand.h" -``` - -## Methods - -```c - void stc64_srandom(uint64_t seed); - uint64_t stc64_random(void); - - 1) stc64_t stc64_init(uint64_t seed); - 2) stc64_t stc64_with_seq(uint64_t seed, uint64_t seq); - - 3) uint64_t stc64_rand(stc64_t* rng); - 4) double stc64_randf(stc64_t* rng); - - 5) stc64_uniform_t stc64_uniform_init(int64_t low, int64_t high); - 6) int64_t stc64_uniform(stc64_t* rng, stc64_uniform_t* dist); - 7) stc64_uniformf_t stc64_uniformf_init(double low, double high); - 8) double stc64_uniformf(stc64_t* rng, stc64_uniformf_t* dist); - - 9) stc64_normalf_t stc64_normalf_init(double mean, double stddev); -10) double stc64_normalf(stc64_t* rng, stc64_normalf_t* dist); -``` -`1-2)` PRNG 64-bit engine initializers. `3)` Integer generator, range \[0, 2^64). -`4)` Double RNG with range \[0, 1). `5-6)` Uniform integer RNG with range \[*low*, *high*]. -`7-8)` Uniform double RNG with range \[*low*, *high*). `9-10)` Normal-distributed double -RNG, around 68% of the values fall within the range [*mean* - *stddev*, *mean* + *stddev*]. - -## Example -```c -#include -#include -#include -#include "stc/crand.h" -#include "stc/cstr.h" -#include "stc/cmap.h" -#include "stc/cvec.h" - -// Declare unordered map: int -> int with typetag 'i'. -using_cmap(i, int, size_t); - -// Comparison of map keys. -static int compare(cmap_i_value_t *a, cmap_i_value_t *b) { - return c_default_compare(&a->first, &b->first); -} -// Declare vector of map entries, with comparison function. -using_cvec(e, cmap_i_value_t, compare); - - -int main() -{ - enum {N = 10000000}; - const double Mean = -12.0, StdDev = 6.0, Scale = 74; - - printf("Demo of gaussian / normal distribution of %d random samples\n", N); - - // Setup random engine with normal distribution. - uint64_t seed = time(NULL); - stc64_t rng = stc64_init(seed); - stc64_normalf_t dist = stc64_normalf_init(Mean, StdDev); - - // Create histogram map - cmap_i mhist = cmap_i_init(); - for (size_t i = 0; i < N; ++i) { - int index = (int) round( stc64_normalf(&rng, &dist) ); - cmap_i_emplace(&mhist, index, 0).first->second += 1; - } - - // Transfer map to vec and sort it by map entry keys. - cvec_e vhist = cvec_e_init(); - c_foreach (i, cmap_i, mhist) - cvec_e_push_back(&vhist, *i.ref); - cvec_e_sort(&vhist); - - // Print the gaussian bar chart - cstr_t bar = cstr_init(); - c_foreach (i, cvec_e, vhist) { - size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / N); - if (n > 0) { - cstr_resize(&bar, n, '*'); - printf("%4d %s\n", i.ref->first, bar.str); - } - } - - // Cleanup - cstr_del(&bar); - cmap_i_del(&mhist); - cvec_e_del(&vhist); -} -``` -Output: -``` -Demo of gaussian / normal distribution of 10000000 random samples - -29 * - -28 ** - -27 *** - -26 **** - -25 ******* - -24 ********* - -23 ************* - -22 ****************** - -21 *********************** - -20 ****************************** - -19 ************************************* - -18 ******************************************** - -17 **************************************************** - -16 *********************************************************** - -15 ***************************************************************** - -14 ********************************************************************* - -13 ************************************************************************ - -12 ************************************************************************* - -11 ************************************************************************ - -10 ********************************************************************* - -9 ***************************************************************** - -8 *********************************************************** - -7 **************************************************** - -6 ******************************************** - -5 ************************************* - -4 ****************************** - -3 *********************** - -2 ****************** - -1 ************* - 0 ********* - 1 ******* - 2 **** - 3 *** - 4 ** - 5 * -``` diff --git a/docs/crandom_api.md b/docs/crandom_api.md new file mode 100644 index 00000000..c8ad34ff --- /dev/null +++ b/docs/crandom_api.md @@ -0,0 +1,165 @@ +# STC Module [crandom](../stc/crandom.h): Pseudo Random Number Generators +![Random](pics/random.jpg) + +This describes the API of module **crandom**. It contains **stc64**, a *64-bit PRNG*, and can generate +bounded uniform and normal distributed random numbers. See [random](https://en.cppreference.com/w/cpp/header/random) +for similar c++ functionality. + +**stc64** is an extremely fast PRNG by Tyge Løvset, suited for parallel usage. It features a +Weyl-sequence as part of the state. It is faster than *sfc64*, *wyhash64*, *pcg64*, and *xoshiro256\*\** +on common platforms. It does not require fast multiplication or 128-bit integer operations. It has a +256 bit state, but updates only 192 bit per generated number. + +There is no *jump function*, but by incrementing the Weyl-increment by 2, it starts a new +unique 2^64 *minimum* length period. Note that for each Weyl-increment (state[3]), the period +length is about 2^126 with a high probability. For a single thread, a minimum period of 2^127 +is generated when the Weyl-increment is incremented by 2 every 2^64 output. + +**stc64** passes *PractRand*, tested up to 8TB output, Vigna's Hamming weight test, and simple +correlation tests, i.e. *n* interleaved streams with only one-bit differences in initial state. + +See the PRNG shootout by Vigna: http://prng.di.unimi.it and the debate between the authors of +xoshiro and pcg (Vigna/O'Neill) PRNGs: https://www.pcg-random.org/posts/on-vignas-pcg-critique.html + +## Types + +| Name | Type definition | Used to represent... | +|:-------------------|:------------------------------------------|:-----------------------------| +| `stc64_t` | `struct {uint64_t state[4];}` | The PRNG engine type | +| `stc64_uniform_t` | `struct {int64_t lower; uint64_t range;}` | Integer uniform distribution | +| `stc64_uniformf_t` | `struct {double lower, range;}` | Real number uniform distr. | +| `stc64_normalf_t` | `struct {double mean, stddev;}` | Normal distribution type | + +## Header file + +All cstr definitions and prototypes may be included in your C source file by including a single header file. +```c +#include "stc/crandom.h" +``` + +## Methods + +```c + void stc64_srandom(uint64_t seed); + uint64_t stc64_random(void); + + 1) stc64_t stc64_init(uint64_t seed); + 2) stc64_t stc64_with_seq(uint64_t seed, uint64_t seq); + + 3) uint64_t stc64_rand(stc64_t* rng); + 4) double stc64_randf(stc64_t* rng); + + 5) stc64_uniform_t stc64_uniform_init(int64_t low, int64_t high); + 6) int64_t stc64_uniform(stc64_t* rng, stc64_uniform_t* dist); + 7) stc64_uniformf_t stc64_uniformf_init(double low, double high); + 8) double stc64_uniformf(stc64_t* rng, stc64_uniformf_t* dist); + + 9) stc64_normalf_t stc64_normalf_init(double mean, double stddev); +10) double stc64_normalf(stc64_t* rng, stc64_normalf_t* dist); +``` +`1-2)` PRNG 64-bit engine initializers. `3)` Integer generator, range \[0, 2^64). +`4)` Double RNG with range \[0, 1). `5-6)` Uniform integer RNG with range \[*low*, *high*]. +`7-8)` Uniform double RNG with range \[*low*, *high*). `9-10)` Normal-distributed double +RNG, around 68% of the values fall within the range [*mean* - *stddev*, *mean* + *stddev*]. + +## Example +```c +#include +#include +#include +#include "stc/crandom.h" +#include "stc/cstr.h" +#include "stc/cmap.h" +#include "stc/cvec.h" + +// Declare unordered map: int -> int with typetag 'i'. +using_cmap(i, int, size_t); + +// Comparison of map keys. +static int compare(cmap_i_value_t *a, cmap_i_value_t *b) { + return c_default_compare(&a->first, &b->first); +} +// Declare vector of map entries, with comparison function. +using_cvec(e, cmap_i_value_t, compare); + + +int main() +{ + enum {N = 10000000}; + const double Mean = -12.0, StdDev = 6.0, Scale = 74; + + printf("Demo of gaussian / normal distribution of %d random samples\n", N); + + // Setup random engine with normal distribution. + uint64_t seed = time(NULL); + stc64_t rng = stc64_init(seed); + stc64_normalf_t dist = stc64_normalf_init(Mean, StdDev); + + // Create histogram map + cmap_i mhist = cmap_i_init(); + for (size_t i = 0; i < N; ++i) { + int index = (int) round( stc64_normalf(&rng, &dist) ); + cmap_i_emplace(&mhist, index, 0).first->second += 1; + } + + // Transfer map to vec and sort it by map entry keys. + cvec_e vhist = cvec_e_init(); + c_foreach (i, cmap_i, mhist) + cvec_e_push_back(&vhist, *i.ref); + cvec_e_sort(&vhist); + + // Print the gaussian bar chart + cstr_t bar = cstr_init(); + c_foreach (i, cvec_e, vhist) { + size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", i.ref->first, bar.str); + } + } + + // Cleanup + cstr_del(&bar); + cmap_i_del(&mhist); + cvec_e_del(&vhist); +} +``` +Output: +``` +Demo of gaussian / normal distribution of 10000000 random samples + -29 * + -28 ** + -27 *** + -26 **** + -25 ******* + -24 ********* + -23 ************* + -22 ****************** + -21 *********************** + -20 ****************************** + -19 ************************************* + -18 ******************************************** + -17 **************************************************** + -16 *********************************************************** + -15 ***************************************************************** + -14 ********************************************************************* + -13 ************************************************************************ + -12 ************************************************************************* + -11 ************************************************************************ + -10 ********************************************************************* + -9 ***************************************************************** + -8 *********************************************************** + -7 **************************************************** + -6 ******************************************** + -5 ************************************* + -4 ****************************** + -3 *********************** + -2 ****************** + -1 ************* + 0 ********* + 1 ******* + 2 **** + 3 *** + 4 ** + 5 * +``` -- cgit v1.2.3