Add graph references
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# Declare the files needed to compile our vendored copy of the PCG random
|
||||
# number generator
|
||||
add_library(
|
||||
pcg
|
||||
OBJECT
|
||||
EXCLUDE_FROM_ALL
|
||||
pcg-advance-64.c
|
||||
pcg-advance-128.c
|
||||
pcg-output-32.c
|
||||
pcg-output-64.c
|
||||
pcg-output-128.c
|
||||
pcg-rngs-64.c
|
||||
pcg-rngs-128.c
|
||||
)
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set_property(TARGET pcg PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
use_all_warnings(pcg)
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* PCG Random Number Generation for C.
|
||||
*
|
||||
* Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>,
|
||||
* and the PCG Project contributors.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (provided in
|
||||
* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* or under the MIT license (provided in LICENSE-MIT.txt and at
|
||||
* http://opensource.org/licenses/MIT), at your option. This file may not
|
||||
* be copied, modified, or distributed except according to those terms.
|
||||
*
|
||||
* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See your chosen license for details.
|
||||
*
|
||||
* For additional information about the PCG random number generation scheme,
|
||||
* visit http://www.pcg-random.org/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is derived from the canonical C++ PCG implementation, which
|
||||
* has many additional features and is preferable if you can use C++ in
|
||||
* your project.
|
||||
*
|
||||
* Repetative C code is derived using C preprocessor metaprogramming
|
||||
* techniques.
|
||||
*/
|
||||
|
||||
#include "pcg_variants.h"
|
||||
|
||||
/* Multi-step advance functions (jump-ahead, jump-back)
|
||||
*
|
||||
* The method used here is based on Brown, "Random Number Generation
|
||||
* with Arbitrary Stride,", Transactions of the American Nuclear
|
||||
* Society (Nov. 1994). The algorithm is very similar to fast
|
||||
* exponentiation.
|
||||
*
|
||||
* Even though delta is an unsigned integer, we can pass a
|
||||
* signed integer to go backwards, it just goes "the long way round".
|
||||
*/
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, pcg128_t cur_mult,
|
||||
pcg128_t cur_plus)
|
||||
{
|
||||
pcg128_t acc_mult = 1u;
|
||||
pcg128_t acc_plus = 0u;
|
||||
while (delta > 0) {
|
||||
if (delta & 1) {
|
||||
acc_mult *= cur_mult;
|
||||
acc_plus = acc_plus * cur_mult + cur_plus;
|
||||
}
|
||||
cur_plus = (cur_mult + 1) * cur_plus;
|
||||
cur_mult *= cur_mult;
|
||||
delta /= 2;
|
||||
}
|
||||
return acc_mult * state + acc_plus;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* PCG Random Number Generation for C.
|
||||
*
|
||||
* Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>,
|
||||
* and the PCG Project contributors.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (provided in
|
||||
* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* or under the MIT license (provided in LICENSE-MIT.txt and at
|
||||
* http://opensource.org/licenses/MIT), at your option. This file may not
|
||||
* be copied, modified, or distributed except according to those terms.
|
||||
*
|
||||
* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See your chosen license for details.
|
||||
*
|
||||
* For additional information about the PCG random number generation scheme,
|
||||
* visit http://www.pcg-random.org/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is derived from the canonical C++ PCG implementation, which
|
||||
* has many additional features and is preferable if you can use C++ in
|
||||
* your project.
|
||||
*
|
||||
* Repetative C code is derived using C preprocessor metaprogramming
|
||||
* techniques.
|
||||
*/
|
||||
|
||||
#include "pcg_variants.h"
|
||||
|
||||
/* Multi-step advance functions (jump-ahead, jump-back)
|
||||
*
|
||||
* The method used here is based on Brown, "Random Number Generation
|
||||
* with Arbitrary Stride,", Transactions of the American Nuclear
|
||||
* Society (Nov. 1994). The algorithm is very similar to fast
|
||||
* exponentiation.
|
||||
*
|
||||
* Even though delta is an unsigned integer, we can pass a
|
||||
* signed integer to go backwards, it just goes "the long way round".
|
||||
*/
|
||||
|
||||
uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, uint64_t cur_mult,
|
||||
uint64_t cur_plus)
|
||||
{
|
||||
uint64_t acc_mult = 1u;
|
||||
uint64_t acc_plus = 0u;
|
||||
while (delta > 0) {
|
||||
if (delta & 1) {
|
||||
acc_mult *= cur_mult;
|
||||
acc_plus = acc_plus * cur_mult + cur_plus;
|
||||
}
|
||||
cur_plus = (cur_mult + 1) * cur_plus;
|
||||
cur_mult *= cur_mult;
|
||||
delta /= 2;
|
||||
}
|
||||
return acc_mult * state + acc_plus;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* PCG Random Number Generation for C.
|
||||
*
|
||||
* Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>,
|
||||
* and the PCG Project contributors.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (provided in
|
||||
* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* or under the MIT license (provided in LICENSE-MIT.txt and at
|
||||
* http://opensource.org/licenses/MIT), at your option. This file may not
|
||||
* be copied, modified, or distributed except according to those terms.
|
||||
*
|
||||
* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See your chosen license for details.
|
||||
*
|
||||
* For additional information about the PCG random number generation scheme,
|
||||
* visit http://www.pcg-random.org/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is derived from the canonical C++ PCG implementation, which
|
||||
* has many additional features and is preferable if you can use C++ in
|
||||
* your project.
|
||||
*
|
||||
* The contents of this file were mechanically derived from pcg_variants.h
|
||||
* (every inline function defined there gets a generated extern declaration).
|
||||
*/
|
||||
|
||||
#include "pcg_variants.h"
|
||||
|
||||
/*
|
||||
* Rotate helper functions.
|
||||
*/
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Output functions. These are the core of the PCG generation scheme.
|
||||
*/
|
||||
|
||||
/* XSH RS */
|
||||
|
||||
/* XSH RR */
|
||||
|
||||
/* RXS M XS */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state);
|
||||
#endif
|
||||
|
||||
/* RXS M */
|
||||
|
||||
/* XSL RR (only defined for >= 64 bits) */
|
||||
|
||||
/* XSL RR RR (only defined for >= 64 bits) */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state);
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* PCG Random Number Generation for C.
|
||||
*
|
||||
* Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>,
|
||||
* and the PCG Project contributors.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (provided in
|
||||
* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* or under the MIT license (provided in LICENSE-MIT.txt and at
|
||||
* http://opensource.org/licenses/MIT), at your option. This file may not
|
||||
* be copied, modified, or distributed except according to those terms.
|
||||
*
|
||||
* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See your chosen license for details.
|
||||
*
|
||||
* For additional information about the PCG random number generation scheme,
|
||||
* visit http://www.pcg-random.org/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is derived from the canonical C++ PCG implementation, which
|
||||
* has many additional features and is preferable if you can use C++ in
|
||||
* your project.
|
||||
*
|
||||
* The contents of this file were mechanically derived from pcg_variants.h
|
||||
* (every inline function defined there gets a generated extern declaration).
|
||||
*/
|
||||
|
||||
#include "pcg_variants.h"
|
||||
|
||||
/*
|
||||
* Rotate helper functions.
|
||||
*/
|
||||
|
||||
extern inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot);
|
||||
|
||||
/*
|
||||
* Output functions. These are the core of the PCG generation scheme.
|
||||
*/
|
||||
|
||||
/* XSH RS */
|
||||
|
||||
extern inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state);
|
||||
|
||||
/* XSH RR */
|
||||
|
||||
extern inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state);
|
||||
|
||||
/* RXS M XS */
|
||||
|
||||
extern inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state);
|
||||
|
||||
/* RXS M */
|
||||
|
||||
extern inline uint32_t pcg_output_rxs_m_64_32(uint64_t state);
|
||||
|
||||
/* XSL RR (only defined for >= 64 bits) */
|
||||
|
||||
extern inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state);
|
||||
|
||||
/* XSL RR RR (only defined for >= 64 bits) */
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* PCG Random Number Generation for C.
|
||||
*
|
||||
* Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>,
|
||||
* and the PCG Project contributors.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (provided in
|
||||
* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* or under the MIT license (provided in LICENSE-MIT.txt and at
|
||||
* http://opensource.org/licenses/MIT), at your option. This file may not
|
||||
* be copied, modified, or distributed except according to those terms.
|
||||
*
|
||||
* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See your chosen license for details.
|
||||
*
|
||||
* For additional information about the PCG random number generation scheme,
|
||||
* visit http://www.pcg-random.org/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is derived from the canonical C++ PCG implementation, which
|
||||
* has many additional features and is preferable if you can use C++ in
|
||||
* your project.
|
||||
*
|
||||
* The contents of this file were mechanically derived from pcg_variants.h
|
||||
* (every inline function defined there gets a generated extern declaration).
|
||||
*/
|
||||
|
||||
#include "pcg_variants.h"
|
||||
|
||||
/*
|
||||
* Rotate helper functions.
|
||||
*/
|
||||
|
||||
extern inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot);
|
||||
|
||||
/*
|
||||
* Output functions. These are the core of the PCG generation scheme.
|
||||
*/
|
||||
|
||||
/* XSH RS */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state);
|
||||
#endif
|
||||
|
||||
/* XSH RR */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state);
|
||||
#endif
|
||||
|
||||
/* RXS M XS */
|
||||
|
||||
extern inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state);
|
||||
|
||||
/* RXS M */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t pcg_output_rxs_m_128_64(pcg128_t state);
|
||||
#endif
|
||||
|
||||
/* XSL RR (only defined for >= 64 bits) */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state);
|
||||
#endif
|
||||
|
||||
/* XSL RR RR (only defined for >= 64 bits) */
|
||||
|
||||
extern inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state);
|
||||
+378
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* PCG Random Number Generation for C.
|
||||
*
|
||||
* Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>,
|
||||
* and the PCG Project contributors.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (provided in
|
||||
* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* or under the MIT license (provided in LICENSE-MIT.txt and at
|
||||
* http://opensource.org/licenses/MIT), at your option. This file may not
|
||||
* be copied, modified, or distributed except according to those terms.
|
||||
*
|
||||
* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See your chosen license for details.
|
||||
*
|
||||
* For additional information about the PCG random number generation scheme,
|
||||
* visit http://www.pcg-random.org/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is derived from the canonical C++ PCG implementation, which
|
||||
* has many additional features and is preferable if you can use C++ in
|
||||
* your project.
|
||||
*
|
||||
* The contents of this file were mechanically derived from pcg_variants.h
|
||||
* (every inline function defined there gets a generated extern declaration).
|
||||
*/
|
||||
|
||||
#include "pcg_variants.h"
|
||||
|
||||
/* Functions to advance the underlying LCG, one version for each size and
|
||||
* each style. These functions are considered semi-private. There is rarely
|
||||
* a good reason to call them directly.
|
||||
*/
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_oneseq_128_step_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_oneseq_128_advance_r(struct pcg_state_128* rng,
|
||||
pcg128_t delta);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_mcg_128_step_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_mcg_128_advance_r(struct pcg_state_128* rng,
|
||||
pcg128_t delta);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_unique_128_step_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_unique_128_advance_r(struct pcg_state_128* rng,
|
||||
pcg128_t delta);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128* rng,
|
||||
pcg128_t delta);
|
||||
#endif
|
||||
|
||||
/* Functions to seed the RNG state, one version for each size and each
|
||||
* style. Unlike the step functions, regular users can and should call
|
||||
* these functions.
|
||||
*/
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_oneseq_128_srandom_r(struct pcg_state_128* rng,
|
||||
pcg128_t initstate);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_mcg_128_srandom_r(struct pcg_state_128* rng,
|
||||
pcg128_t initstate);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_unique_128_srandom_r(struct pcg_state_128* rng,
|
||||
pcg128_t initstate);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128* rng,
|
||||
pcg128_t initstate,
|
||||
pcg128_t initseq);
|
||||
#endif
|
||||
|
||||
/* Now, finally we create each of the individual generators. We provide
|
||||
* a random_r function that provides a random number of the appropriate
|
||||
* type (using the full range of the type) and a boundedrand_r version
|
||||
* that provides
|
||||
*
|
||||
* Implementation notes for boundedrand_r:
|
||||
*
|
||||
* To avoid bias, we need to make the range of the RNG a multiple of
|
||||
* bound, which we do by dropping output less than a threshold.
|
||||
* Let's consider a 32-bit case... A naive scheme to calculate the
|
||||
* threshold would be to do
|
||||
*
|
||||
* uint32_t threshold = 0x100000000ull % bound;
|
||||
*
|
||||
* but 64-bit div/mod is slower than 32-bit div/mod (especially on
|
||||
* 32-bit platforms). In essence, we do
|
||||
*
|
||||
* uint32_t threshold = (0x100000000ull-bound) % bound;
|
||||
*
|
||||
* because this version will calculate the same modulus, but the LHS
|
||||
* value is less than 2^32.
|
||||
*
|
||||
* (Note that using modulo is only wise for good RNGs, poorer RNGs
|
||||
* such as raw LCGs do better using a technique based on division.)
|
||||
* Empirical tests show that division is preferable to modulus for
|
||||
* reducing the range of an RNG. It's faster, and sometimes it can
|
||||
* even be statistically prefereable.
|
||||
*/
|
||||
|
||||
/* Generation functions for XSH RS */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, uint64_t bound);
|
||||
#endif
|
||||
|
||||
/* Generation functions for XSH RR */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, uint64_t bound);
|
||||
#endif
|
||||
|
||||
/* Generation functions for RXS M XS (no MCG versions because they
|
||||
* don't make sense when you want to use the entire state)
|
||||
*/
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
|
||||
pcg128_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
|
||||
pcg128_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128* rng,
|
||||
pcg128_t bound);
|
||||
#endif
|
||||
|
||||
/* Generation functions for RXS M */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_128_rxs_m_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_unique_128_rxs_m_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_unique_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_setseq_128_rxs_m_64_random_r(struct pcg_state_setseq_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_setseq_128_rxs_m_64_boundedrand_r(struct pcg_state_setseq_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t pcg_mcg_128_rxs_m_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_mcg_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng, uint64_t bound);
|
||||
#endif
|
||||
|
||||
/* Generation functions for XSL RR (only defined for "large" types) */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
|
||||
uint64_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline uint64_t
|
||||
pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, uint64_t bound);
|
||||
#endif
|
||||
|
||||
/* Generation functions for XSL RR RR (only defined for "large" types) */
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
|
||||
pcg128_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
|
||||
pcg128_t bound);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128* rng);
|
||||
#endif
|
||||
|
||||
#if PCG_HAS_128BIT_OPS
|
||||
extern inline pcg128_t
|
||||
pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128* rng,
|
||||
pcg128_t bound);
|
||||
#endif
|
||||
+255
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* PCG Random Number Generation for C.
|
||||
*
|
||||
* Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>,
|
||||
* and the PCG Project contributors.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (provided in
|
||||
* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* or under the MIT license (provided in LICENSE-MIT.txt and at
|
||||
* http://opensource.org/licenses/MIT), at your option. This file may not
|
||||
* be copied, modified, or distributed except according to those terms.
|
||||
*
|
||||
* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See your chosen license for details.
|
||||
*
|
||||
* For additional information about the PCG random number generation scheme,
|
||||
* visit http://www.pcg-random.org/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is derived from the canonical C++ PCG implementation, which
|
||||
* has many additional features and is preferable if you can use C++ in
|
||||
* your project.
|
||||
*
|
||||
* The contents of this file were mechanically derived from pcg_variants.h
|
||||
* (every inline function defined there gets a generated extern declaration).
|
||||
*/
|
||||
|
||||
#include "pcg_variants.h"
|
||||
|
||||
/* Functions to advance the underlying LCG, one version for each size and
|
||||
* each style. These functions are considered semi-private. There is rarely
|
||||
* a good reason to call them directly.
|
||||
*/
|
||||
|
||||
extern inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline void pcg_oneseq_64_advance_r(struct pcg_state_64* rng,
|
||||
uint64_t delta);
|
||||
|
||||
extern inline void pcg_mcg_64_step_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline void pcg_mcg_64_advance_r(struct pcg_state_64* rng,
|
||||
uint64_t delta);
|
||||
|
||||
extern inline void pcg_unique_64_step_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline void pcg_unique_64_advance_r(struct pcg_state_64* rng,
|
||||
uint64_t delta);
|
||||
|
||||
extern inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64* rng);
|
||||
|
||||
extern inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64* rng,
|
||||
uint64_t delta);
|
||||
|
||||
/* Functions to seed the RNG state, one version for each size and each
|
||||
* style. Unlike the step functions, regular users can and should call
|
||||
* these functions.
|
||||
*/
|
||||
|
||||
extern inline void pcg_oneseq_64_srandom_r(struct pcg_state_64* rng,
|
||||
uint64_t initstate);
|
||||
|
||||
extern inline void pcg_mcg_64_srandom_r(struct pcg_state_64* rng,
|
||||
uint64_t initstate);
|
||||
|
||||
extern inline void pcg_unique_64_srandom_r(struct pcg_state_64* rng,
|
||||
uint64_t initstate);
|
||||
|
||||
extern inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64* rng,
|
||||
uint64_t initstate,
|
||||
uint64_t initseq);
|
||||
|
||||
/* Now, finally we create each of the individual generators. We provide
|
||||
* a random_r function that provides a random number of the appropriate
|
||||
* type (using the full range of the type) and a boundedrand_r version
|
||||
* that provides
|
||||
*
|
||||
* Implementation notes for boundedrand_r:
|
||||
*
|
||||
* To avoid bias, we need to make the range of the RNG a multiple of
|
||||
* bound, which we do by dropping output less than a threshold.
|
||||
* Let's consider a 32-bit case... A naive scheme to calculate the
|
||||
* threshold would be to do
|
||||
*
|
||||
* uint32_t threshold = 0x100000000ull % bound;
|
||||
*
|
||||
* but 64-bit div/mod is slower than 32-bit div/mod (especially on
|
||||
* 32-bit platforms). In essence, we do
|
||||
*
|
||||
* uint32_t threshold = (0x100000000ull-bound) % bound;
|
||||
*
|
||||
* because this version will calculate the same modulus, but the LHS
|
||||
* value is less than 2^32.
|
||||
*
|
||||
* (Note that using modulo is only wise for good RNGs, poorer RNGs
|
||||
* such as raw LCGs do better using a technique based on division.)
|
||||
* Empirical tests show that division is preferable to modulus for
|
||||
* reducing the range of an RNG. It's faster, and sometimes it can
|
||||
* even be statistically prefereable.
|
||||
*/
|
||||
|
||||
/* Generation functions for XSH RS */
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64* rng,
|
||||
uint32_t bound);
|
||||
|
||||
extern inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
/* Generation functions for XSH RR */
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
|
||||
uint32_t bound);
|
||||
|
||||
extern inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
/* Generation functions for RXS M XS (no MCG versions because they
|
||||
* don't make sense when you want to use the entire state)
|
||||
*/
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
|
||||
uint64_t bound);
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
|
||||
uint64_t bound);
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64* rng);
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64* rng,
|
||||
uint64_t bound);
|
||||
|
||||
/* Generation functions for RXS M */
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_oneseq_64_rxs_m_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_oneseq_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_unique_64_rxs_m_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_unique_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_setseq_64_rxs_m_32_random_r(struct pcg_state_setseq_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_setseq_64_rxs_m_32_boundedrand_r(struct pcg_state_setseq_64* rng,
|
||||
uint32_t bound);
|
||||
|
||||
extern inline uint32_t pcg_mcg_64_rxs_m_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_mcg_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
/* Generation functions for XSL RR (only defined for "large" types) */
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
|
||||
uint32_t bound);
|
||||
|
||||
extern inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint32_t
|
||||
pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
|
||||
|
||||
/* Generation functions for XSL RR RR (only defined for "large" types) */
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
|
||||
uint64_t bound);
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng);
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
|
||||
uint64_t bound);
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64* rng);
|
||||
|
||||
extern inline uint64_t
|
||||
pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64* rng,
|
||||
uint64_t bound);
|
||||
+2557
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user