diff options
Diffstat (limited to 'src')
52 files changed, 4371 insertions, 6 deletions
diff --git a/src/haversine/build.sh b/src/haversine/build.sh new file mode 100755 index 0000000..38170c0 --- /dev/null +++ b/src/haversine/build.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +cd "$(dirname "$(readlink -f "$0")")" + +Build="../../build" +mkdir -p "$Build" +mkdir -p generated + +Compiler="clang" + +CompilerFlags=" +-g +-fdiagnostics-absolute-paths +-nostdinc++ +" + +WarningFlags=" +-Wall +-Wextra +-Wno-unused-label +-Wno-unused-variable +-Wno-unused-function +-Wno-unused-value +-Wno-unused-but-set-variable +-Wno-missing-field-initializers +-Wno-write-strings +-Wno-unused-parameter +" + +LinkerFlags="-lm" + +printf '[debug mode]\n' +printf '[%s build]\n' "$Compiler" +$Compiler $CompilerFlags $WarningFlags $LinkerFlags \ + -o "$Build"/haversine_generator \ + haversine_generator.cpp
\ No newline at end of file diff --git a/src/haversine/haversine_generator.cpp b/src/haversine/haversine_generator.cpp new file mode 100644 index 0000000..c3f7561 --- /dev/null +++ b/src/haversine/haversine_generator.cpp @@ -0,0 +1,138 @@ +#include "libs/lr/lr.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> + +#define MemoryCopy memcpy + +#include "listing_065.cpp" + +#include "haversine_random.h" + +enum generation_method : u32 +{ + Method_Uniform, + Method_Cluster +}; + +int main(int ArgsCount, char *Args[], char *Env[]) +{ + // 1. haversine_generator [uniform/cluster] [random seed] [number of pairs to generate] + + if(ArgsCount >= 4) + { + u32 Method = 0; + u64 RandomSeed = 0;; + u64 PairsCount = 0; + b32 Error = false; + + if(!strcmp(Args[1], "uniform")) + { + Method = Method_Uniform; + } + else if(!strcmp(Args[1], "cluster")) + { + Method = Method_Cluster; + } + else + { + Error = true; + } + + RandomSeed = atoll(Args[2]); + + if(RandomSeed == 0) + { + if(Args[2][0] == '0') + { + RandomSeed = 0; + } + else + { + Error = true; + } + } + + PairsCount = atoll(Args[3]); + if(PairsCount == 0) + { + Error = true; + } + + if(!Error) + { + printf("Method: %s\n" + "Random seed: %lu\n" + "Pairs count: %lu\n" + , Args[1], RandomSeed, PairsCount); + + // Generate pairs in the following format. + // + // { + // "pairs": + // [ + // { "x0": ..., "y0": ..., "x1": ..., "y1": ... }, + // { "x0": ..., "y0": ..., "x1": ..., "y1": ... } + // ] + // } + // + + FILE *Out = fopen("out.json", "wb"); + char *JsonHeader = + "{\n" + " \"pairs\":\n" + " [\n"; + char *JsonFooter = + " ]\n" + "}\n"; + + fprintf(Out, "%s", JsonHeader); + + pcg64_random_t RNG = {}; + pcg64_srandom_r(&RNG, RandomSeed, RandomSeed); + + f64 AverageSum = 0; + f64 TotalSum = 0; + for(u64 PairsIndex = 0; + PairsIndex < PairsCount; + PairsIndex++) + { + b32 LastPair = false; + + f64 X0 = RandomBetween(&RNG, -180.0, 180.0); + f64 Y0 = RandomBetween(&RNG, -360.0, 360.0); + f64 X1 = RandomBetween(&RNG, -180.0, 180.0); + f64 Y1 = RandomBetween(&RNG, -360.0, 360.0); + + f64 Sum = ReferenceHaversine(X0, Y0, X1, Y1, 6372.8); + TotalSum += Sum; + + // NOTE(luca): A double's mantissa is 52 bits. 2^52 - 1 is 4503599627370495 which has + // 16 digits. + fprintf(Out, + " { \"x0\": %.15f, \"y0\": %.15f, \"x1\": %.15f, \"y1\": %.15f }\n", + X0, Y0, X1, Y1); + + } + AverageSum = TotalSum / (f64)PairsCount; + + fprintf(Out, "%s", JsonFooter); + + printf("Average sum: %f\n", AverageSum); + } + else + { + printf("Usage: %s [uniform/cluster] [random seed] [number of pairs to generate]\n", + Args[0]); + } + } + else + { + printf("Usage: %s [uniform/cluster] [random seed] [number of pairs to generate]\n", + Args[0]); + } + + return 0; +}
\ No newline at end of file diff --git a/src/haversine/haversine_random.h b/src/haversine/haversine_random.h new file mode 100644 index 0000000..b7c545e --- /dev/null +++ b/src/haversine/haversine_random.h @@ -0,0 +1,107 @@ + +#include <math.h> + +#include "libs/pcg/pcg.c" + +#define CountLeadingZeroes64(Value) __builtin_clzll(Value) + +u64 +RandomU64(pcg64_random_t *RNG) +{ + u64 Result = pcg64_random_r(RNG); + return Result; +} + +//~ Random 64 bit float + +// From: https://mumble.net/~campbell/tmp/random_real.c +/* + * Copyright (c) 2014, Taylor R Campbell +* +* Verbatim copying and distribution of this entire article are +* permitted worldwide, without royalty, in any medium, provided +* this notice, and the copyright notice, are preserved. +* +*/ + +/* + * random_real: Generate a stream of bits uniformly at random and + * interpret it as the fractional part of the binary expansion of a + * number in [0, 1], 0.00001010011111010100...; then round it. + */ +f64 +RandomF64(pcg64_random_t *RNG) +{ + s32 Exponent = -64; + u64 Significand; + umm Shift; + + /* + * Read zeros into the exponent until we hit a one; the rest + * will go into the significand. + */ + while((Significand = RandomU64(RNG)) == 0) + { + Exponent -= 64; + /* + * If the exponent falls below -1074 = emin + 1 - p, + * the exponent of the smallest subnormal, we are + * guaranteed the result will be rounded to zero. This + * case is so unlikely it will happen in realistic + * terms only if RandomU64 is broken. + */ + if ((Exponent < -1074)) + return 0; + } + + /* + * There is a 1 somewhere in significand, not necessarily in + * the most significant position. If there are leading zeros, + * shift them into the exponent and refill the less-significant + * bits of the significand. Can't predict one way or another + * whether there are leading zeros: there's a fifty-fifty + * chance, if RandomU64() is uniformly distributed. + */ + Shift = CountLeadingZeroes64(Significand); + if (Shift != 0) { + Exponent -= Shift; + Significand <<= Shift; + Significand |= (RandomU64(RNG) >> (64 - Shift)); + } + + /* + * Set the sticky bit, since there is almost surely another 1 + * in the bit stream. Otherwise, we might round what looks + * like a tie to even when, almost surely, were we to look + * further in the bit stream, there would be a 1 breaking the + * tie. + */ + Significand |= 1; + + /* + * Finally, convert to f64 (rounding) and scale by + * 2^exponent. + */ + return ldexp((f64)Significand, Exponent); +} + +f64 +RandomUnilateral(pcg64_random_t *RNG) +{ + return RandomF64(RNG); +} + +f64 +RandomBilateral(pcg64_random_t *RNG) +{ + f64 Result = 2.0*RandomUnilateral(RNG) - 1.0; + return Result; +} + +f64 +RandomBetween(pcg64_random_t *RNG, f64 Min, f64 Max) +{ + f64 Range = Max - Min; + f64 Result = Min + RandomUnilateral(RNG)*Range; + return Result; +}
\ No newline at end of file diff --git a/src/haversine/libs/lr/lr.h b/src/haversine/libs/lr/lr.h new file mode 120000 index 0000000..49fb375 --- /dev/null +++ b/src/haversine/libs/lr/lr.h @@ -0,0 +1 @@ +/home/aluc/proj/lr/lr.h
\ No newline at end of file diff --git a/src/haversine/libs/lr/lr_macros.h b/src/haversine/libs/lr/lr_macros.h new file mode 120000 index 0000000..530249a --- /dev/null +++ b/src/haversine/libs/lr/lr_macros.h @@ -0,0 +1 @@ +/home/aluc/proj/lr/lr_macros.h
\ No newline at end of file diff --git a/src/haversine/libs/lr/lr_platform.h b/src/haversine/libs/lr/lr_platform.h new file mode 120000 index 0000000..e387ee2 --- /dev/null +++ b/src/haversine/libs/lr/lr_platform.h @@ -0,0 +1 @@ +/home/aluc/proj/lr/lr_platform.h
\ No newline at end of file diff --git a/src/haversine/libs/lr/lr_types.h b/src/haversine/libs/lr/lr_types.h new file mode 120000 index 0000000..6d2fa08 --- /dev/null +++ b/src/haversine/libs/lr/lr_types.h @@ -0,0 +1 @@ +/home/aluc/proj/lr/lr_types.h
\ No newline at end of file diff --git a/src/haversine/libs/pcg/pcg-advance-128.c b/src/haversine/libs/pcg/pcg-advance-128.c new file mode 100644 index 0000000..be72009 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-advance-128.c @@ -0,0 +1,64 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 + diff --git a/src/haversine/libs/pcg/pcg-advance-16.c b/src/haversine/libs/pcg/pcg-advance-16.c new file mode 100644 index 0000000..11461d9 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-advance-16.c @@ -0,0 +1,62 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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". + */ + +uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta, uint16_t cur_mult, + uint16_t cur_plus) +{ + uint16_t acc_mult = 1u; + uint16_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; +} + diff --git a/src/haversine/libs/pcg/pcg-advance-32.c b/src/haversine/libs/pcg/pcg-advance-32.c new file mode 100644 index 0000000..76f35fc --- /dev/null +++ b/src/haversine/libs/pcg/pcg-advance-32.c @@ -0,0 +1,62 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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". + */ + +uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta, uint32_t cur_mult, + uint32_t cur_plus) +{ + uint32_t acc_mult = 1u; + uint32_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; +} + diff --git a/src/haversine/libs/pcg/pcg-advance-64.c b/src/haversine/libs/pcg/pcg-advance-64.c new file mode 100644 index 0000000..8210e75 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-advance-64.c @@ -0,0 +1,62 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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; +} + diff --git a/src/haversine/libs/pcg/pcg-advance-8.c b/src/haversine/libs/pcg/pcg-advance-8.c new file mode 100644 index 0000000..8280958 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-advance-8.c @@ -0,0 +1,62 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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". + */ + +uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult, + uint8_t cur_plus) +{ + uint8_t acc_mult = 1u; + uint8_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; +} + diff --git a/src/haversine/libs/pcg/pcg-global-32.c b/src/haversine/libs/pcg/pcg-global-32.c new file mode 100644 index 0000000..8c18e48 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-global-32.c @@ -0,0 +1,56 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#include "pcg_variants.h" + +static pcg32_random_t pcg32_global = PCG32_INITIALIZER; + +uint32_t pcg32_random() +{ + return pcg32_random_r(&pcg32_global); +} + +uint32_t pcg32_boundedrand(uint32_t bound) +{ + return pcg32_boundedrand_r(&pcg32_global, bound); +} + +void pcg32_srandom(uint64_t seed, uint64_t seq) +{ + pcg32_srandom_r(&pcg32_global, seed, seq); +} + +void pcg32_advance(uint64_t delta) +{ + return pcg32_advance_r(&pcg32_global, delta); +} + diff --git a/src/haversine/libs/pcg/pcg-global-64.c b/src/haversine/libs/pcg/pcg-global-64.c new file mode 100644 index 0000000..26aa677 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-global-64.c @@ -0,0 +1,59 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#include "pcg_variants.h" + +#if PCG_HAS_128BIT_OPS + +static pcg64_random_t pcg64_global = PCG64_INITIALIZER; + +uint64_t pcg64_random() +{ + return pcg64_random_r(&pcg64_global); +} + +uint64_t pcg64_boundedrand(uint64_t bound) +{ + return pcg64_boundedrand_r(&pcg64_global, bound); +} + +void pcg64_srandom(pcg128_t seed, pcg128_t seq) +{ + pcg64_srandom_r(&pcg64_global, seed, seq); +} + +void pcg64_advance(pcg128_t delta) +{ + pcg64_advance_r(&pcg64_global, delta); +} + +#endif diff --git a/src/haversine/libs/pcg/pcg-output-128.c b/src/haversine/libs/pcg/pcg-output-128.c new file mode 100644 index 0000000..cb2142e --- /dev/null +++ b/src/haversine/libs/pcg/pcg-output-128.c @@ -0,0 +1,64 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#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 + +// 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 + diff --git a/src/haversine/libs/pcg/pcg-output-16.c b/src/haversine/libs/pcg/pcg-output-16.c new file mode 100644 index 0000000..c593f67 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-output-16.c @@ -0,0 +1,60 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#include "pcg_variants.h" + +/* + * Rotate helper functions. + */ + +extern inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot); + +/* + * Output functions. These are the core of the PCG generation scheme. + */ + +// XSH RS + +extern inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state); + +// XSH RR + +extern inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state); + +// RXS M XS + +extern inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state); + +// XSL RR (only defined for >= 64 bits) + +// XSL RR RR (only defined for >= 64 bits) + diff --git a/src/haversine/libs/pcg/pcg-output-32.c b/src/haversine/libs/pcg/pcg-output-32.c new file mode 100644 index 0000000..e291c36 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-output-32.c @@ -0,0 +1,62 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#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); + +// 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) + diff --git a/src/haversine/libs/pcg/pcg-output-64.c b/src/haversine/libs/pcg/pcg-output-64.c new file mode 100644 index 0000000..8c6b7e4 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-output-64.c @@ -0,0 +1,70 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#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); + +// 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); + diff --git a/src/haversine/libs/pcg/pcg-output-8.c b/src/haversine/libs/pcg/pcg-output-8.c new file mode 100644 index 0000000..83fe449 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-output-8.c @@ -0,0 +1,60 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#include "pcg_variants.h" + +/* + * Rotate helper functions. + */ + +extern inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot); + +/* + * Output functions. These are the core of the PCG generation scheme. + */ + +// XSH RS + +extern inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state); + +// XSH RR + +extern inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state); + +// RXS M XS + +extern inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state); + +// XSL RR (only defined for >= 64 bits) + +// XSL RR RR (only defined for >= 64 bits) + diff --git a/src/haversine/libs/pcg/pcg-rngs-128.c b/src/haversine/libs/pcg/pcg-rngs-128.c new file mode 100644 index 0000000..8023589 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-rngs-128.c @@ -0,0 +1,337 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#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.) + * Empricical tests show that division is preferable to modulus for + * reducting 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 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 + diff --git a/src/haversine/libs/pcg/pcg-rngs-16.c b/src/haversine/libs/pcg/pcg-rngs-16.c new file mode 100644 index 0000000..6d4e9b6 --- /dev/null +++ b/src/haversine/libs/pcg/pcg-rngs-16.c @@ -0,0 +1,183 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#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_16_step_r(struct pcg_state_16* rng); + +extern inline void pcg_oneseq_16_advance_r(struct pcg_state_16* rng, + uint16_t delta); + +extern inline void pcg_mcg_16_step_r(struct pcg_state_16* rng); + +extern inline void pcg_mcg_16_advance_r(struct pcg_state_16* rng, + uint16_t delta); + +extern inline void pcg_unique_16_step_r(struct pcg_state_16* rng); + +extern inline void pcg_unique_16_advance_r(struct pcg_state_16* rng, + uint16_t delta); + +extern inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16* rng); + +extern inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16* rng, + uint16_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_16_srandom_r(struct pcg_state_16* rng, + uint16_t initstate); + +extern inline void pcg_mcg_16_srandom_r(struct pcg_state_16* rng, + uint16_t initstate); + +extern inline void pcg_unique_16_srandom_r(struct pcg_state_16* rng, + uint16_t initstate); + +extern inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16* rng, + uint16_t initstate, + uint16_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.) + * Empricical tests show that division is preferable to modulus for + * reducting the range of an RNG. It's faster, and sometimes it can + * even be statistically prefereable. + */ + +/* Generation functions for XSH RS */ + +extern inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16* rng); + +extern inline uint8_t +pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound); + +extern inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16* rng); + +extern inline uint8_t +pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound); + +extern inline uint8_t +pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16* rng); + +extern inline uint8_t +pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16* rng, + uint8_t bound); + +extern inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16* rng); + +extern inline uint8_t +pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound); + +/* Generation functions for XSH RR */ + +extern inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16* rng); + +extern inline uint8_t +pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound); + +extern inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16* rng); + +extern inline uint8_t +pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound); + +extern inline uint8_t +pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16* rng); + +extern inline uint8_t +pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16* rng, + uint8_t bound); + +extern inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16* rng); + +extern inline uint8_t +pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, uint8_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 uint16_t +pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng); + +extern inline uint16_t +pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng, + uint16_t bound); + +extern inline uint16_t +pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng); + +extern inline uint16_t +pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng, + uint16_t bound); + +extern inline uint16_t +pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16* rng); + +extern inline uint16_t +pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16* rng, + uint16_t bound); + +/* Generation functions for XSL RR (only defined for "large" types) */ + +/* Generation functions for XSL RR RR (only defined for "large" types) */ + diff --git a/src/haversine/libs/pcg/pcg-rngs-32.c b/src/haversine/libs/pcg/pcg-rngs-32.c new file mode 100644 index 0000000..1c8da7e --- /dev/null +++ b/src/haversine/libs/pcg/pcg-rngs-32.c @@ -0,0 +1,187 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#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_32_step_r(struct pcg_state_32* rng); + +extern inline void pcg_oneseq_32_advance_r(struct pcg_state_32* rng, + uint32_t delta); + +extern inline void pcg_mcg_32_step_r(struct pcg_state_32* rng); + +extern inline void pcg_mcg_32_advance_r(struct pcg_state_32* rng, + uint32_t delta); + +extern inline void pcg_unique_32_step_r(struct pcg_state_32* rng); + +extern inline void pcg_unique_32_advance_r(struct pcg_state_32* rng, + uint32_t delta); + +extern inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32* rng); + +extern inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32* rng, + uint32_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_32_srandom_r(struct pcg_state_32* rng, + uint32_t initstate); + +extern inline void pcg_mcg_32_srandom_r(struct pcg_state_32* rng, + uint32_t initstate); + +extern inline void pcg_unique_32_srandom_r(struct pcg_state_32* rng, + uint32_t initstate); + +extern inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32* rng, + uint32_t initstate, + uint32_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.) + * Empricical tests show that division is preferable to modulus for + * reducting the range of an RNG. It's faster, and sometimes it can + * even be statistically prefereable. + */ + +/* Generation functions for XSH RS */ + +extern inline uint16_t +pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32* rng); + +extern inline uint16_t +pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound); + +extern inline uint16_t +pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32* rng); + +extern inline uint16_t +pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound); + +extern inline uint16_t +pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32* rng); + +extern inline uint16_t +pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32* rng, + uint16_t bound); + +extern inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32* rng); + +extern inline uint16_t +pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound); + +/* Generation functions for XSH RR */ + +extern inline uint16_t +pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32* rng); + +extern inline uint16_t +pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound); + +extern inline uint16_t +pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32* rng); + +extern inline uint16_t +pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound); + +extern inline uint16_t +pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32* rng); + +extern inline uint16_t +pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32* rng, + uint16_t bound); + +extern inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32* rng); + +extern inline uint16_t +pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, uint16_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 uint32_t +pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng); + +extern inline uint32_t +pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng, + uint32_t bound); + +extern inline uint32_t +pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng); + +extern inline uint32_t +pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng, + uint32_t bound); + +extern inline uint32_t +pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32* rng); + +extern inline uint32_t +pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32* rng, + uint32_t bound); + +/* Generation functions for XSL RR (only defined for "large" types) */ + +/* Generation functions for XSL RR RR (only defined for "large" types) */ + diff --git a/src/haversine/libs/pcg/pcg-rngs-64.c b/src/haversine/libs/pcg/pcg-rngs-64.c new file mode 100644 index 0000000..cc0ff2c --- /dev/null +++ b/src/haversine/libs/pcg/pcg-rngs-64.c @@ -0,0 +1,232 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#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.) + * Empricical tests show that division is preferable to modulus for + * reducting 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 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); + diff --git a/src/haversine/libs/pcg/pcg-rngs-8.c b/src/haversine/libs/pcg/pcg-rngs-8.c new file mode 100644 index 0000000..8779aac --- /dev/null +++ b/src/haversine/libs/pcg/pcg-rngs-8.c @@ -0,0 +1,128 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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 an exern declaration here). + */ + +#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_8_step_r(struct pcg_state_8* rng); + +extern inline void pcg_oneseq_8_advance_r(struct pcg_state_8* rng, + uint8_t delta); + +extern inline void pcg_mcg_8_step_r(struct pcg_state_8* rng); + +extern inline void pcg_mcg_8_advance_r(struct pcg_state_8* rng, uint8_t delta); + +extern inline void pcg_unique_8_step_r(struct pcg_state_8* rng); + +extern inline void pcg_unique_8_advance_r(struct pcg_state_8* rng, + uint8_t delta); + +extern inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8* rng); + +extern inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8* rng, + uint8_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_8_srandom_r(struct pcg_state_8* rng, + uint8_t initstate); + +extern inline void pcg_mcg_8_srandom_r(struct pcg_state_8* rng, + uint8_t initstate); + +extern inline void pcg_unique_8_srandom_r(struct pcg_state_8* rng, + uint8_t initstate); + +extern inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8* rng, + uint8_t initstate, uint8_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.) + * Empricical tests show that division is preferable to modulus for + * reducting the range of an RNG. It's faster, and sometimes it can + * even be statistically prefereable. + */ + +/* Generation functions for XSH RS */ + +/* Generation functions for XSH RR */ + +/* 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 uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8* rng); + +extern inline uint8_t +pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8* rng, uint8_t bound); + +extern inline uint8_t +pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8* rng); + +extern inline uint8_t +pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8* rng, + uint8_t bound); + +/* Generation functions for XSL RR (only defined for "large" types) */ + +/* Generation functions for XSL RR RR (only defined for "large" types) */ + diff --git a/src/haversine/libs/pcg/pcg.c b/src/haversine/libs/pcg/pcg.c new file mode 100644 index 0000000..cf29e6d --- /dev/null +++ b/src/haversine/libs/pcg/pcg.c @@ -0,0 +1,16 @@ +#include "pcg_variants.h" +#include "pcg-advance-128.c" +#include "pcg-advance-16.c" +#include "pcg-advance-32.c" +#include "pcg-advance-64.c" +#include "pcg-advance-8.c" +#include "pcg-output-128.c" +#include "pcg-output-16.c" +#include "pcg-output-32.c" +#include "pcg-output-64.c" +#include "pcg-output-8.c" +#include "pcg-rngs-128.c" +#include "pcg-rngs-16.c" +#include "pcg-rngs-32.c" +#include "pcg-rngs-64.c" +#include "pcg-rngs-8.c" diff --git a/src/haversine/libs/pcg/pcg_variants.h b/src/haversine/libs/pcg/pcg_variants.h new file mode 100644 index 0000000..83edae8 --- /dev/null +++ b/src/haversine/libs/pcg/pcg_variants.h @@ -0,0 +1,2213 @@ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For additional information about the PCG random number generation scheme, + * including its license and other licensing options, 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. + * + * Much of the derivation was performed mechanically. In particular, the + * output functions were generated by compiling the C++ output functions + * into LLVM bitcode and then transforming that using the LLVM C backend + * (from https://github.com/draperlaboratory/llvm-cbe), and then + * postprocessing and hand editing the output. + * + * Much of the remaining code was generated by C-preprocessor metaprogramming. + */ + +#ifndef PCG_VARIANTS_H_INCLUDED +#define PCG_VARIANTS_H_INCLUDED 1 + +#include <inttypes.h> + +#if __SIZEOF_INT128__ +typedef __uint128_t pcg128_t; +#define PCG_128BIT_CONSTANT(high,low) \ +((((pcg128_t)high) << 64) + low) +#define PCG_HAS_128BIT_OPS 1 +#else +#error "non" +#endif + +#if __GNUC_GNU_INLINE__ && !defined(__cplusplus) +#error Nonstandard GNU inlining semanatics. Compile with -std=c99 or better. +// We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE +// but better to just reject ancient C code. +#endif + +#if __cplusplus +extern "C" { +#endif + + /* + * Rotate helper functions. + */ + + inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot) + { + /* Unfortunately, clang is kinda pathetic when it comes to properly + * recognizing idiomatic rotate code, so for clang we actually provide + * assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss. + */ +#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) + asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); + return value; +#else + return (value >> rot) | (value << ((- rot) & 7)); +#endif + } + + inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot) + { +#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) + asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); + return value; +#else + return (value >> rot) | (value << ((- rot) & 15)); +#endif + } + + inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot) + { +#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) + asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); + return value; +#else + return (value >> rot) | (value << ((- rot) & 31)); +#endif + } + + inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot) + { +#if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__ + // For whatever reason, clang actually *does* generator rotq by + // itself, so we don't need this code. + asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); + return value; +#else + return (value >> rot) | (value << ((- rot) & 63)); +#endif + } + +#if PCG_HAS_128BIT_OPS + inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot) + { + return (value >> rot) | (value << ((- rot) & 127)); + } +#endif + + /* + * Output functions. These are the core of the PCG generation scheme. + */ + + // XSH RS + + inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state) + { + return (uint8_t)(((state >> 7u) ^ state) >> ((state >> 14u) + 3u)); + } + + inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state) + { + return (uint16_t)(((state >> 11u) ^ state) >> ((state >> 30u) + 11u)); + } + + inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state) + { + + return (uint32_t)(((state >> 22u) ^ state) >> ((state >> 61u) + 22u)); + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state) + { + return (uint64_t)(((state >> 43u) ^ state) >> ((state >> 124u) + 45u)); + } +#endif + + // XSH RR + + inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state) + { + return pcg_rotr_8(((state >> 5u) ^ state) >> 5u, state >> 13u); + } + + inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state) + { + return pcg_rotr_16(((state >> 10u) ^ state) >> 12u, state >> 28u); + } + + inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state) + { + return pcg_rotr_32(((state >> 18u) ^ state) >> 27u, state >> 59u); + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state) + { + return pcg_rotr_64(((state >> 29u) ^ state) >> 58u, state >> 122u); + } +#endif + + // RXS M XS + + inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state) + { + uint8_t word = ((state >> ((state >> 6u) + 2u)) ^ state) * 217u; + return (word >> 6u) ^ word; + } + + inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state) + { + uint16_t word = ((state >> ((state >> 13u) + 3u)) ^ state) * 62169u; + return (word >> 11u) ^ word; + } + + inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state) + { + uint32_t word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; + return (word >> 22u) ^ word; + } + + inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state) + { + uint64_t word = ((state >> ((state >> 59u) + 5u)) ^ state) + * 12605985483714917081ull; + return (word >> 43u) ^ word; + } + +#if PCG_HAS_128BIT_OPS + inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state) + { + pcg128_t word = ((state >> ((state >> 122u) + 6u)) ^ state) + * (PCG_128BIT_CONSTANT(17766728186571221404ULL, + 12605985483714917081ULL)); + // 327738287884841127335028083622016905945 + return (word >> 86u) ^ word; + } +#endif + + // XSL RR (only defined for >= 64 bits) + + inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state) + { + return pcg_rotr_32(((uint32_t)(state >> 32u)) ^ (uint32_t)state, + state >> 59u); + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state) + { + return pcg_rotr_64(((uint64_t)(state >> 64u)) ^ (uint64_t)state, + state >> 122u); + } +#endif + + // XSL RR RR (only defined for >= 64 bits) + + inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state) + { + uint32_t rot1 = (uint32_t)(state >> 59u); + uint32_t high = (uint32_t)(state >> 32u); + uint32_t low = (uint32_t)state; + uint32_t xored = high ^ low; + uint32_t newlow = pcg_rotr_32(xored, rot1); + uint32_t newhigh = pcg_rotr_32(high, newlow & 31u); + return (((uint64_t)newhigh) << 32u) | newlow; + } + +#if PCG_HAS_128BIT_OPS + inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state) + { + uint32_t rot1 = (uint32_t)(state >> 122u); + uint64_t high = (uint64_t)(state >> 64u); + uint64_t low = (uint64_t)state; + uint64_t xored = high ^ low; + uint64_t newlow = pcg_rotr_64(xored, rot1); + uint64_t newhigh = pcg_rotr_64(high, newlow & 63u); + return (((pcg128_t)newhigh) << 64u) | newlow; + } +#endif + +#define PCG_DEFAULT_MULTIPLIER_8 141U +#define PCG_DEFAULT_MULTIPLIER_16 12829U +#define PCG_DEFAULT_MULTIPLIER_32 747796405U +#define PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL + +#define PCG_DEFAULT_INCREMENT_8 77U +#define PCG_DEFAULT_INCREMENT_16 47989U +#define PCG_DEFAULT_INCREMENT_32 2891336453U +#define PCG_DEFAULT_INCREMENT_64 1442695040888963407ULL + +#if PCG_HAS_128BIT_OPS +#define PCG_DEFAULT_MULTIPLIER_128 \ +PCG_128BIT_CONSTANT(2549297995355413924ULL,4865540595714422341ULL) +#define PCG_DEFAULT_INCREMENT_128 \ +PCG_128BIT_CONSTANT(6364136223846793005ULL,1442695040888963407ULL) +#endif + + /* + * Static initialization constants (if you can't call srandom for some + * bizarre reason). + */ + +#if PCG_HAS_128BIT_OPS +#define PCG_STATE_ONESEQ_8_INITIALIZER { 0xd7U } +#define PCG_STATE_ONESEQ_16_INITIALIZER { 0x20dfU } +#define PCG_STATE_ONESEQ_32_INITIALIZER { 0x46b56677U } +#define PCG_STATE_ONESEQ_64_INITIALIZER { 0x4d595df4d0f33173ULL } +#define PCG_STATE_ONESEQ_128_INITIALIZER \ +{ PCG_128BIT_CONSTANT(0xb8dc10e158a92392ULL, 0x98046df007ec0a53ULL) } +#endif + +#if PCG_HAS_128BIT_OPS +#define PCG_STATE_UNIQUE_8_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER +#define PCG_STATE_UNIQUE_16_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER +#define PCG_STATE_UNIQUE_32_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER +#define PCG_STATE_UNIQUE_64_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER +#define PCG_STATE_UNIQUE_128_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER +#endif + +#if PCG_HAS_128BIT_OPS +#define PCG_STATE_MCG_8_INITIALIZER { 0xe5U } +#define PCG_STATE_MCG_16_INITIALIZER { 0xa5e5U } +#define PCG_STATE_MCG_32_INITIALIZER { 0xd15ea5e5U } +#define PCG_STATE_MCG_64_INITIALIZER { 0xcafef00dd15ea5e5ULL } +#define PCG_STATE_MCG_128_INITIALIZER \ +{ PCG_128BIT_CONSTANT(0x0000000000000000ULL, 0xcafef00dd15ea5e5ULL) } +#endif + +#if PCG_HAS_128BIT_OPS +#define PCG_STATE_SETSEQ_8_INITIALIZER { 0x9bU, 0xdbU } +#define PCG_STATE_SETSEQ_16_INITIALIZER { 0xe39bU, 0x5bdbU } +#define PCG_STATE_SETSEQ_32_INITIALIZER { 0xec02d89bU, 0x94b95bdbU } +#define PCG_STATE_SETSEQ_64_INITIALIZER \ +{ 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL } +#define PCG_STATE_SETSEQ_128_INITIALIZER \ +{ PCG_128BIT_CONSTANT(0x979c9a98d8462005ULL, 0x7d3e9cb6cfe0549bULL), \ +PCG_128BIT_CONSTANT(0x0000000000000001ULL, 0xda3e39cb94b95bdbULL) } +#endif + + /* Representations for the oneseq, mcg, and unique variants */ + + struct pcg_state_8 { + uint8_t state; + }; + + struct pcg_state_16 { + uint16_t state; + }; + + struct pcg_state_32 { + uint32_t state; + }; + + struct pcg_state_64 { + uint64_t state; + }; + +#if PCG_HAS_128BIT_OPS + struct pcg_state_128 { + pcg128_t state; + }; +#endif + + /* Representations setseq variants */ + + struct pcg_state_setseq_8 { + uint8_t state; + uint8_t inc; + }; + + struct pcg_state_setseq_16 { + uint16_t state; + uint16_t inc; + }; + + struct pcg_state_setseq_32 { + uint32_t state; + uint32_t inc; + }; + + struct pcg_state_setseq_64 { + uint64_t state; + uint64_t inc; + }; + +#if PCG_HAS_128BIT_OPS + struct pcg_state_setseq_128 { + pcg128_t state; + pcg128_t inc; + }; +#endif + + /* Multi-step advance functions (jump-ahead, jump-back) */ + + extern uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult, + uint8_t cur_plus); + extern uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta, + uint16_t cur_mult, uint16_t cur_plus); + extern uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta, + uint32_t cur_mult, uint32_t cur_plus); + extern uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, + uint64_t cur_mult, uint64_t cur_plus); + +#if PCG_HAS_128BIT_OPS + extern pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, + pcg128_t cur_mult, pcg128_t cur_plus); +#endif + + /* 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. + */ + + inline void pcg_oneseq_8_step_r(struct pcg_state_8* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + + PCG_DEFAULT_INCREMENT_8; + } + + inline void pcg_oneseq_8_advance_r(struct pcg_state_8* rng, uint8_t delta) + { + rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, + PCG_DEFAULT_INCREMENT_8); + } + + inline void pcg_mcg_8_step_r(struct pcg_state_8* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8; + } + + inline void pcg_mcg_8_advance_r(struct pcg_state_8* rng, uint8_t delta) + { + rng->state + = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 0u); + } + + inline void pcg_unique_8_step_r(struct pcg_state_8* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + + (uint8_t)(((intptr_t)rng) | 1u); + } + + inline void pcg_unique_8_advance_r(struct pcg_state_8* rng, uint8_t delta) + { + rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, + (uint8_t)(((intptr_t)rng) | 1u)); + } + + inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + rng->inc; + } + + inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8* rng, + uint8_t delta) + { + rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, + rng->inc); + } + + inline void pcg_oneseq_16_step_r(struct pcg_state_16* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 + + PCG_DEFAULT_INCREMENT_16; + } + + inline void pcg_oneseq_16_advance_r(struct pcg_state_16* rng, uint16_t delta) + { + rng->state = pcg_advance_lcg_16( + rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, PCG_DEFAULT_INCREMENT_16); + } + + inline void pcg_mcg_16_step_r(struct pcg_state_16* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16; + } + + inline void pcg_mcg_16_advance_r(struct pcg_state_16* rng, uint16_t delta) + { + rng->state + = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, 0u); + } + + inline void pcg_unique_16_step_r(struct pcg_state_16* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 + + (uint16_t)(((intptr_t)rng) | 1u); + } + + inline void pcg_unique_16_advance_r(struct pcg_state_16* rng, uint16_t delta) + { + rng->state + = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, + (uint16_t)(((intptr_t)rng) | 1u)); + } + + inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 + rng->inc; + } + + inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16* rng, + uint16_t delta) + { + rng->state = pcg_advance_lcg_16(rng->state, delta, + PCG_DEFAULT_MULTIPLIER_16, rng->inc); + } + + inline void pcg_oneseq_32_step_r(struct pcg_state_32* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 + + PCG_DEFAULT_INCREMENT_32; + } + + inline void pcg_oneseq_32_advance_r(struct pcg_state_32* rng, uint32_t delta) + { + rng->state = pcg_advance_lcg_32( + rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, PCG_DEFAULT_INCREMENT_32); + } + + inline void pcg_mcg_32_step_r(struct pcg_state_32* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32; + } + + inline void pcg_mcg_32_advance_r(struct pcg_state_32* rng, uint32_t delta) + { + rng->state + = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, 0u); + } + + inline void pcg_unique_32_step_r(struct pcg_state_32* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 + + (uint32_t)(((intptr_t)rng) | 1u); + } + + inline void pcg_unique_32_advance_r(struct pcg_state_32* rng, uint32_t delta) + { + rng->state + = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, + (uint32_t)(((intptr_t)rng) | 1u)); + } + + inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 + rng->inc; + } + + inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32* rng, + uint32_t delta) + { + rng->state = pcg_advance_lcg_32(rng->state, delta, + PCG_DEFAULT_MULTIPLIER_32, rng->inc); + } + + inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + + PCG_DEFAULT_INCREMENT_64; + } + + inline void pcg_oneseq_64_advance_r(struct pcg_state_64* rng, uint64_t delta) + { + rng->state = pcg_advance_lcg_64( + rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, PCG_DEFAULT_INCREMENT_64); + } + + inline void pcg_mcg_64_step_r(struct pcg_state_64* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64; + } + + inline void pcg_mcg_64_advance_r(struct pcg_state_64* rng, uint64_t delta) + { + rng->state + = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, 0u); + } + + inline void pcg_unique_64_step_r(struct pcg_state_64* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + + (uint64_t)(((intptr_t)rng) | 1u); + } + + inline void pcg_unique_64_advance_r(struct pcg_state_64* rng, uint64_t delta) + { + rng->state + = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, + (uint64_t)(((intptr_t)rng) | 1u)); + } + + inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + rng->inc; + } + + inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64* rng, + uint64_t delta) + { + rng->state = pcg_advance_lcg_64(rng->state, delta, + PCG_DEFAULT_MULTIPLIER_64, rng->inc); + } + +#if PCG_HAS_128BIT_OPS + inline void pcg_oneseq_128_step_r(struct pcg_state_128* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + + PCG_DEFAULT_INCREMENT_128; + } +#endif + +#if PCG_HAS_128BIT_OPS + inline void pcg_oneseq_128_advance_r(struct pcg_state_128* rng, pcg128_t delta) + { + rng->state + = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128, + PCG_DEFAULT_INCREMENT_128); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline void pcg_mcg_128_step_r(struct pcg_state_128* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128; + } +#endif + +#if PCG_HAS_128BIT_OPS + inline void pcg_mcg_128_advance_r(struct pcg_state_128* rng, pcg128_t delta) + { + rng->state = pcg_advance_lcg_128(rng->state, delta, + PCG_DEFAULT_MULTIPLIER_128, 0u); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline void pcg_unique_128_step_r(struct pcg_state_128* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + + (pcg128_t)(((intptr_t)rng) | 1u); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline void pcg_unique_128_advance_r(struct pcg_state_128* rng, pcg128_t delta) + { + rng->state + = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128, + (pcg128_t)(((intptr_t)rng) | 1u)); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128* rng) + { + rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + rng->inc; + } +#endif + +#if PCG_HAS_128BIT_OPS + inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128* rng, + pcg128_t delta) + { + rng->state = pcg_advance_lcg_128(rng->state, delta, + PCG_DEFAULT_MULTIPLIER_128, rng->inc); + } +#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. + */ + + inline void pcg_oneseq_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate) + { + rng->state = 0U; + pcg_oneseq_8_step_r(rng); + rng->state += initstate; + pcg_oneseq_8_step_r(rng); + } + + inline void pcg_mcg_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate) + { + rng->state = initstate | 1u; + } + + inline void pcg_unique_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate) + { + rng->state = 0U; + pcg_unique_8_step_r(rng); + rng->state += initstate; + pcg_unique_8_step_r(rng); + } + + inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8* rng, + uint8_t initstate, uint8_t initseq) + { + rng->state = 0U; + rng->inc = (initseq << 1u) | 1u; + pcg_setseq_8_step_r(rng); + rng->state += initstate; + pcg_setseq_8_step_r(rng); + } + + inline void pcg_oneseq_16_srandom_r(struct pcg_state_16* rng, + uint16_t initstate) + { + rng->state = 0U; + pcg_oneseq_16_step_r(rng); + rng->state += initstate; + pcg_oneseq_16_step_r(rng); + } + + inline void pcg_mcg_16_srandom_r(struct pcg_state_16* rng, uint16_t initstate) + { + rng->state = initstate | 1u; + } + + inline void pcg_unique_16_srandom_r(struct pcg_state_16* rng, + uint16_t initstate) + { + rng->state = 0U; + pcg_unique_16_step_r(rng); + rng->state += initstate; + pcg_unique_16_step_r(rng); + } + + inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16* rng, + uint16_t initstate, uint16_t initseq) + { + rng->state = 0U; + rng->inc = (initseq << 1u) | 1u; + pcg_setseq_16_step_r(rng); + rng->state += initstate; + pcg_setseq_16_step_r(rng); + } + + inline void pcg_oneseq_32_srandom_r(struct pcg_state_32* rng, + uint32_t initstate) + { + rng->state = 0U; + pcg_oneseq_32_step_r(rng); + rng->state += initstate; + pcg_oneseq_32_step_r(rng); + } + + inline void pcg_mcg_32_srandom_r(struct pcg_state_32* rng, uint32_t initstate) + { + rng->state = initstate | 1u; + } + + inline void pcg_unique_32_srandom_r(struct pcg_state_32* rng, + uint32_t initstate) + { + rng->state = 0U; + pcg_unique_32_step_r(rng); + rng->state += initstate; + pcg_unique_32_step_r(rng); + } + + inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32* rng, + uint32_t initstate, uint32_t initseq) + { + rng->state = 0U; + rng->inc = (initseq << 1u) | 1u; + pcg_setseq_32_step_r(rng); + rng->state += initstate; + pcg_setseq_32_step_r(rng); + } + + inline void pcg_oneseq_64_srandom_r(struct pcg_state_64* rng, + uint64_t initstate) + { + rng->state = 0U; + pcg_oneseq_64_step_r(rng); + rng->state += initstate; + pcg_oneseq_64_step_r(rng); + } + + inline void pcg_mcg_64_srandom_r(struct pcg_state_64* rng, uint64_t initstate) + { + rng->state = initstate | 1u; + } + + inline void pcg_unique_64_srandom_r(struct pcg_state_64* rng, + uint64_t initstate) + { + rng->state = 0U; + pcg_unique_64_step_r(rng); + rng->state += initstate; + pcg_unique_64_step_r(rng); + } + + inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64* rng, + uint64_t initstate, uint64_t initseq) + { + rng->state = 0U; + rng->inc = (initseq << 1u) | 1u; + pcg_setseq_64_step_r(rng); + rng->state += initstate; + pcg_setseq_64_step_r(rng); + } + +#if PCG_HAS_128BIT_OPS + inline void pcg_oneseq_128_srandom_r(struct pcg_state_128* rng, + pcg128_t initstate) + { + rng->state = 0U; + pcg_oneseq_128_step_r(rng); + rng->state += initstate; + pcg_oneseq_128_step_r(rng); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline void pcg_mcg_128_srandom_r(struct pcg_state_128* rng, pcg128_t initstate) + { + rng->state = initstate | 1u; + } +#endif + +#if PCG_HAS_128BIT_OPS + inline void pcg_unique_128_srandom_r(struct pcg_state_128* rng, + pcg128_t initstate) + { + rng->state = 0U; + pcg_unique_128_step_r(rng); + rng->state += initstate; + pcg_unique_128_step_r(rng); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128* rng, + pcg128_t initstate, pcg128_t initseq) + { + rng->state = 0U; + rng->inc = (initseq << 1u) | 1u; + pcg_setseq_128_step_r(rng); + rng->state += initstate; + pcg_setseq_128_step_r(rng); + } +#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.) + * Empricical tests show that division is preferable to modulus for + * reducting the range of an RNG. It's faster, and sometimes it can + * even be statistically prefereable. + */ + + /* Generation functions for XSH RS */ + + inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16* rng) + { + uint16_t oldstate = rng->state; + pcg_oneseq_16_step_r(rng); + return pcg_output_xsh_rs_16_8(oldstate); + } + + inline uint8_t pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, + uint8_t bound) + { + uint8_t threshold = ((uint8_t)(-bound)) % bound; + for (;;) { + uint8_t r = pcg_oneseq_16_xsh_rs_8_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint16_t pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32* rng) + { + uint32_t oldstate = rng->state; + pcg_oneseq_32_step_r(rng); + return pcg_output_xsh_rs_32_16(oldstate); + } + + inline uint16_t pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_oneseq_32_xsh_rs_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_oneseq_64_step_r(rng); + return pcg_output_xsh_rs_64_32(oldstate); + } + + inline uint32_t pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_oneseq_64_xsh_rs_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128* rng) + { + pcg_oneseq_128_step_r(rng); + return pcg_output_xsh_rs_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_oneseq_128_xsh_rs_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16* rng) + { + uint16_t oldstate = rng->state; + pcg_unique_16_step_r(rng); + return pcg_output_xsh_rs_16_8(oldstate); + } + + inline uint8_t pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, + uint8_t bound) + { + uint8_t threshold = ((uint8_t)(-bound)) % bound; + for (;;) { + uint8_t r = pcg_unique_16_xsh_rs_8_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint16_t pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32* rng) + { + uint32_t oldstate = rng->state; + pcg_unique_32_step_r(rng); + return pcg_output_xsh_rs_32_16(oldstate); + } + + inline uint16_t pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_unique_32_xsh_rs_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_unique_64_step_r(rng); + return pcg_output_xsh_rs_64_32(oldstate); + } + + inline uint32_t pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_unique_64_xsh_rs_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128* rng) + { + pcg_unique_128_step_r(rng); + return pcg_output_xsh_rs_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_unique_128_xsh_rs_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint8_t pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16* rng) + { + uint16_t oldstate = rng->state; + pcg_setseq_16_step_r(rng); + return pcg_output_xsh_rs_16_8(oldstate); + } + + inline uint8_t + pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16* rng, + uint8_t bound) + { + uint8_t threshold = ((uint8_t)(-bound)) % bound; + for (;;) { + uint8_t r = pcg_setseq_16_xsh_rs_8_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint16_t + pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32* rng) + { + uint32_t oldstate = rng->state; + pcg_setseq_32_step_r(rng); + return pcg_output_xsh_rs_32_16(oldstate); + } + + inline uint16_t + pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_setseq_32_xsh_rs_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t + pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64* rng) + { + uint64_t oldstate = rng->state; + pcg_setseq_64_step_r(rng); + return pcg_output_xsh_rs_64_32(oldstate); + } + + inline uint32_t + pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_setseq_64_xsh_rs_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128* rng) + { + pcg_setseq_128_step_r(rng); + return pcg_output_xsh_rs_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_setseq_128_xsh_rs_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16* rng) + { + uint16_t oldstate = rng->state; + pcg_mcg_16_step_r(rng); + return pcg_output_xsh_rs_16_8(oldstate); + } + + inline uint8_t pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, + uint8_t bound) + { + uint8_t threshold = ((uint8_t)(-bound)) % bound; + for (;;) { + uint8_t r = pcg_mcg_16_xsh_rs_8_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32* rng) + { + uint32_t oldstate = rng->state; + pcg_mcg_32_step_r(rng); + return pcg_output_xsh_rs_32_16(oldstate); + } + + inline uint16_t pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_mcg_32_xsh_rs_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_mcg_64_step_r(rng); + return pcg_output_xsh_rs_64_32(oldstate); + } + + inline uint32_t pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_mcg_64_xsh_rs_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128* rng) + { + pcg_mcg_128_step_r(rng); + return pcg_output_xsh_rs_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_mcg_128_xsh_rs_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + /* Generation functions for XSH RR */ + + inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16* rng) + { + uint16_t oldstate = rng->state; + pcg_oneseq_16_step_r(rng); + return pcg_output_xsh_rr_16_8(oldstate); + } + + inline uint8_t pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, + uint8_t bound) + { + uint8_t threshold = ((uint8_t)(-bound)) % bound; + for (;;) { + uint8_t r = pcg_oneseq_16_xsh_rr_8_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint16_t pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32* rng) + { + uint32_t oldstate = rng->state; + pcg_oneseq_32_step_r(rng); + return pcg_output_xsh_rr_32_16(oldstate); + } + + inline uint16_t pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_oneseq_32_xsh_rr_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_oneseq_64_step_r(rng); + return pcg_output_xsh_rr_64_32(oldstate); + } + + inline uint32_t pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_oneseq_64_xsh_rr_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128* rng) + { + pcg_oneseq_128_step_r(rng); + return pcg_output_xsh_rr_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_oneseq_128_xsh_rr_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16* rng) + { + uint16_t oldstate = rng->state; + pcg_unique_16_step_r(rng); + return pcg_output_xsh_rr_16_8(oldstate); + } + + inline uint8_t pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, + uint8_t bound) + { + uint8_t threshold = ((uint8_t)(-bound)) % bound; + for (;;) { + uint8_t r = pcg_unique_16_xsh_rr_8_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint16_t pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32* rng) + { + uint32_t oldstate = rng->state; + pcg_unique_32_step_r(rng); + return pcg_output_xsh_rr_32_16(oldstate); + } + + inline uint16_t pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_unique_32_xsh_rr_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_unique_64_step_r(rng); + return pcg_output_xsh_rr_64_32(oldstate); + } + + inline uint32_t pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_unique_64_xsh_rr_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128* rng) + { + pcg_unique_128_step_r(rng); + return pcg_output_xsh_rr_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_unique_128_xsh_rr_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint8_t pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16* rng) + { + uint16_t oldstate = rng->state; + pcg_setseq_16_step_r(rng); + return pcg_output_xsh_rr_16_8(oldstate); + } + + inline uint8_t + pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16* rng, + uint8_t bound) + { + uint8_t threshold = ((uint8_t)(-bound)) % bound; + for (;;) { + uint8_t r = pcg_setseq_16_xsh_rr_8_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint16_t + pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32* rng) + { + uint32_t oldstate = rng->state; + pcg_setseq_32_step_r(rng); + return pcg_output_xsh_rr_32_16(oldstate); + } + + inline uint16_t + pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_setseq_32_xsh_rr_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t + pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64* rng) + { + uint64_t oldstate = rng->state; + pcg_setseq_64_step_r(rng); + return pcg_output_xsh_rr_64_32(oldstate); + } + + inline uint32_t + pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_setseq_64_xsh_rr_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128* rng) + { + pcg_setseq_128_step_r(rng); + return pcg_output_xsh_rr_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_setseq_128_xsh_rr_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16* rng) + { + uint16_t oldstate = rng->state; + pcg_mcg_16_step_r(rng); + return pcg_output_xsh_rr_16_8(oldstate); + } + + inline uint8_t pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, + uint8_t bound) + { + uint8_t threshold = ((uint8_t)(-bound)) % bound; + for (;;) { + uint8_t r = pcg_mcg_16_xsh_rr_8_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32* rng) + { + uint32_t oldstate = rng->state; + pcg_mcg_32_step_r(rng); + return pcg_output_xsh_rr_32_16(oldstate); + } + + inline uint16_t pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_mcg_32_xsh_rr_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_mcg_64_step_r(rng); + return pcg_output_xsh_rr_64_32(oldstate); + } + + inline uint32_t pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_mcg_64_xsh_rr_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128* rng) + { + pcg_mcg_128_step_r(rng); + return pcg_output_xsh_rr_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_mcg_128_xsh_rr_64_random_r(rng); + if (r >= threshold) + return r % 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) + */ + + inline uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8* rng) + { + uint8_t oldstate = rng->state; + pcg_oneseq_8_step_r(rng); + return pcg_output_rxs_m_xs_8_8(oldstate); + } + + inline uint8_t pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8* rng, + uint8_t bound) + { + uint8_t threshold = ((uint8_t)(-bound)) % bound; + for (;;) { + uint8_t r = pcg_oneseq_8_rxs_m_xs_8_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint16_t pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng) + { + uint16_t oldstate = rng->state; + pcg_oneseq_16_step_r(rng); + return pcg_output_rxs_m_xs_16_16(oldstate); + } + + inline uint16_t + pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_oneseq_16_rxs_m_xs_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng) + { + uint32_t oldstate = rng->state; + pcg_oneseq_32_step_r(rng); + return pcg_output_rxs_m_xs_32_32(oldstate); + } + + inline uint32_t + pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_oneseq_32_rxs_m_xs_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint64_t pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_oneseq_64_step_r(rng); + return pcg_output_rxs_m_xs_64_64(oldstate); + } + + inline uint64_t + pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_oneseq_64_rxs_m_xs_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline pcg128_t pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng) + { + pcg_oneseq_128_step_r(rng); + return pcg_output_rxs_m_xs_128_128(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline pcg128_t + pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng, + pcg128_t bound) + { + pcg128_t threshold = -bound % bound; + for (;;) { + pcg128_t r = pcg_oneseq_128_rxs_m_xs_128_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint16_t pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng) + { + uint16_t oldstate = rng->state; + pcg_unique_16_step_r(rng); + return pcg_output_rxs_m_xs_16_16(oldstate); + } + + inline uint16_t + pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_unique_16_rxs_m_xs_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng) + { + uint32_t oldstate = rng->state; + pcg_unique_32_step_r(rng); + return pcg_output_rxs_m_xs_32_32(oldstate); + } + + inline uint32_t + pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_unique_32_rxs_m_xs_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint64_t pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_unique_64_step_r(rng); + return pcg_output_rxs_m_xs_64_64(oldstate); + } + + inline uint64_t + pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_unique_64_rxs_m_xs_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline pcg128_t pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng) + { + pcg_unique_128_step_r(rng); + return pcg_output_rxs_m_xs_128_128(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline pcg128_t + pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng, + pcg128_t bound) + { + pcg128_t threshold = -bound % bound; + for (;;) { + pcg128_t r = pcg_unique_128_rxs_m_xs_128_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint8_t pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8* rng) + { + uint8_t oldstate = rng->state; + pcg_setseq_8_step_r(rng); + return pcg_output_rxs_m_xs_8_8(oldstate); + } + + inline uint8_t + pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8* rng, + uint8_t bound) + { + uint8_t threshold = ((uint8_t)(-bound)) % bound; + for (;;) { + uint8_t r = pcg_setseq_8_rxs_m_xs_8_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint16_t + pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16* rng) + { + uint16_t oldstate = rng->state; + pcg_setseq_16_step_r(rng); + return pcg_output_rxs_m_xs_16_16(oldstate); + } + + inline uint16_t + pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16* rng, + uint16_t bound) + { + uint16_t threshold = ((uint16_t)(-bound)) % bound; + for (;;) { + uint16_t r = pcg_setseq_16_rxs_m_xs_16_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint32_t + pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32* rng) + { + uint32_t oldstate = rng->state; + pcg_setseq_32_step_r(rng); + return pcg_output_rxs_m_xs_32_32(oldstate); + } + + inline uint32_t + pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_setseq_32_rxs_m_xs_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + + inline uint64_t + pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64* rng) + { + uint64_t oldstate = rng->state; + pcg_setseq_64_step_r(rng); + return pcg_output_rxs_m_xs_64_64(oldstate); + } + + inline uint64_t + pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_setseq_64_rxs_m_xs_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline pcg128_t + pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128* rng) + { + pcg_setseq_128_step_r(rng); + return pcg_output_rxs_m_xs_128_128(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline pcg128_t + pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128* rng, + pcg128_t bound) + { + pcg128_t threshold = -bound % bound; + for (;;) { + pcg128_t r = pcg_setseq_128_rxs_m_xs_128_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + /* Generation functions for XSL RR (only defined for "large" types) */ + + inline uint32_t pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_oneseq_64_step_r(rng); + return pcg_output_xsl_rr_64_32(oldstate); + } + + inline uint32_t pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_oneseq_64_xsl_rr_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128* rng) + { + pcg_oneseq_128_step_r(rng); + return pcg_output_xsl_rr_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_oneseq_128_xsl_rr_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint32_t pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_unique_64_step_r(rng); + return pcg_output_xsl_rr_64_32(oldstate); + } + + inline uint32_t pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_unique_64_xsl_rr_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128* rng) + { + pcg_unique_128_step_r(rng); + return pcg_output_xsl_rr_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_unique_128_xsl_rr_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint32_t + pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64* rng) + { + uint64_t oldstate = rng->state; + pcg_setseq_64_step_r(rng); + return pcg_output_xsl_rr_64_32(oldstate); + } + + inline uint32_t + pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_setseq_64_xsl_rr_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128* rng) + { + pcg_setseq_128_step_r(rng); + return pcg_output_xsl_rr_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t + pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_setseq_128_xsl_rr_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_mcg_64_step_r(rng); + return pcg_output_xsl_rr_64_32(oldstate); + } + + inline uint32_t pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, + uint32_t bound) + { + uint32_t threshold = -bound % bound; + for (;;) { + uint32_t r = pcg_mcg_64_xsl_rr_32_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128* rng) + { + pcg_mcg_128_step_r(rng); + return pcg_output_xsl_rr_128_64(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline uint64_t pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_mcg_128_xsl_rr_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + /* Generation functions for XSL RR RR (only defined for "large" types) */ + + inline uint64_t pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_oneseq_64_step_r(rng); + return pcg_output_xsl_rr_rr_64_64(oldstate); + } + + inline uint64_t + pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_oneseq_64_xsl_rr_rr_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline pcg128_t pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng) + { + pcg_oneseq_128_step_r(rng); + return pcg_output_xsl_rr_rr_128_128(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline pcg128_t + pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng, + pcg128_t bound) + { + pcg128_t threshold = -bound % bound; + for (;;) { + pcg128_t r = pcg_oneseq_128_xsl_rr_rr_128_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint64_t pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng) + { + uint64_t oldstate = rng->state; + pcg_unique_64_step_r(rng); + return pcg_output_xsl_rr_rr_64_64(oldstate); + } + + inline uint64_t + pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_unique_64_xsl_rr_rr_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline pcg128_t pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng) + { + pcg_unique_128_step_r(rng); + return pcg_output_xsl_rr_rr_128_128(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline pcg128_t + pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng, + pcg128_t bound) + { + pcg128_t threshold = -bound % bound; + for (;;) { + pcg128_t r = pcg_unique_128_xsl_rr_rr_128_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + inline uint64_t + pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64* rng) + { + uint64_t oldstate = rng->state; + pcg_setseq_64_step_r(rng); + return pcg_output_xsl_rr_rr_64_64(oldstate); + } + + inline uint64_t + pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64* rng, + uint64_t bound) + { + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg_setseq_64_xsl_rr_rr_64_random_r(rng); + if (r >= threshold) + return r % bound; + } + } + +#if PCG_HAS_128BIT_OPS + inline pcg128_t + pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128* rng) + { + pcg_setseq_128_step_r(rng); + return pcg_output_xsl_rr_rr_128_128(rng->state); + } +#endif + +#if PCG_HAS_128BIT_OPS + inline pcg128_t + pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128* rng, + pcg128_t bound) + { + pcg128_t threshold = -bound % bound; + for (;;) { + pcg128_t r = pcg_setseq_128_xsl_rr_rr_128_random_r(rng); + if (r >= threshold) + return r % bound; + } + } +#endif + + //// Typedefs + typedef struct pcg_state_setseq_64 pcg32_random_t; + typedef struct pcg_state_64 pcg32s_random_t; + typedef struct pcg_state_64 pcg32u_random_t; + typedef struct pcg_state_64 pcg32f_random_t; + //// random_r +#define pcg32_random_r pcg_setseq_64_xsh_rr_32_random_r +#define pcg32s_random_r pcg_oneseq_64_xsh_rr_32_random_r +#define pcg32u_random_r pcg_unique_64_xsh_rr_32_random_r +#define pcg32f_random_r pcg_mcg_64_xsh_rs_32_random_r + //// boundedrand_r +#define pcg32_boundedrand_r pcg_setseq_64_xsh_rr_32_boundedrand_r +#define pcg32s_boundedrand_r pcg_oneseq_64_xsh_rr_32_boundedrand_r +#define pcg32u_boundedrand_r pcg_unique_64_xsh_rr_32_boundedrand_r +#define pcg32f_boundedrand_r pcg_mcg_64_xsh_rs_32_boundedrand_r + //// srandom_r +#define pcg32_srandom_r pcg_setseq_64_srandom_r +#define pcg32s_srandom_r pcg_oneseq_64_srandom_r +#define pcg32u_srandom_r pcg_unique_64_srandom_r +#define pcg32f_srandom_r pcg_mcg_64_srandom_r + //// advance_r +#define pcg32_advance_r pcg_setseq_64_advance_r +#define pcg32s_advance_r pcg_oneseq_64_advance_r +#define pcg32u_advance_r pcg_unique_64_advance_r +#define pcg32f_advance_r pcg_mcg_64_advance_r + +#if PCG_HAS_128BIT_OPS + //// Typedefs + typedef struct pcg_state_setseq_128 pcg64_random_t; + typedef struct pcg_state_128 pcg64s_random_t; + typedef struct pcg_state_128 pcg64u_random_t; + typedef struct pcg_state_128 pcg64f_random_t; + //// random_r +#define pcg64_random_r pcg_setseq_128_xsl_rr_64_random_r +#define pcg64s_random_r pcg_oneseq_128_xsl_rr_64_random_r +#define pcg64u_random_r pcg_unique_128_xsl_rr_64_random_r +#define pcg64f_random_r pcg_mcg_128_xsl_rr_64_random_r + //// boundedrand_r +#define pcg64_boundedrand_r pcg_setseq_128_xsl_rr_64_boundedrand_r +#define pcg64s_boundedrand_r pcg_oneseq_128_xsl_rr_64_boundedrand_r +#define pcg64u_boundedrand_r pcg_unique_128_xsl_rr_64_boundedrand_r +#define pcg64f_boundedrand_r pcg_mcg_128_xsl_rr_64_boundedrand_r + //// srandom_r +#define pcg64_srandom_r pcg_setseq_128_srandom_r +#define pcg64s_srandom_r pcg_oneseq_128_srandom_r +#define pcg64u_srandom_r pcg_unique_128_srandom_r +#define pcg64f_srandom_r pcg_mcg_128_srandom_r + //// advance_r +#define pcg64_advance_r pcg_setseq_128_advance_r +#define pcg64s_advance_r pcg_oneseq_128_advance_r +#define pcg64u_advance_r pcg_unique_128_advance_r +#define pcg64f_advance_r pcg_mcg_128_advance_r +#endif + + //// Typedefs + typedef struct pcg_state_8 pcg8si_random_t; + typedef struct pcg_state_16 pcg16si_random_t; + typedef struct pcg_state_32 pcg32si_random_t; + typedef struct pcg_state_64 pcg64si_random_t; + //// random_r +#define pcg8si_random_r pcg_oneseq_8_rxs_m_xs_8_random_r +#define pcg16si_random_r pcg_oneseq_16_rxs_m_xs_16_random_r +#define pcg32si_random_r pcg_oneseq_32_rxs_m_xs_32_random_r +#define pcg64si_random_r pcg_oneseq_64_rxs_m_xs_64_random_r + //// boundedrand_r +#define pcg8si_boundedrand_r pcg_oneseq_8_rxs_m_xs_8_boundedrand_r +#define pcg16si_boundedrand_r pcg_oneseq_16_rxs_m_xs_16_boundedrand_r +#define pcg32si_boundedrand_r pcg_oneseq_32_rxs_m_xs_32_boundedrand_r +#define pcg64si_boundedrand_r pcg_oneseq_64_rxs_m_xs_64_boundedrand_r + //// srandom_r +#define pcg8si_srandom_r pcg_oneseq_8_srandom_r +#define pcg16si_srandom_r pcg_oneseq_16_srandom_r +#define pcg32si_srandom_r pcg_oneseq_32_srandom_r +#define pcg64si_srandom_r pcg_oneseq_64_srandom_r + //// advance_r +#define pcg8si_advance_r pcg_oneseq_8_advance_r +#define pcg16si_advance_r pcg_oneseq_16_advance_r +#define pcg32si_advance_r pcg_oneseq_32_advance_r +#define pcg64si_advance_r pcg_oneseq_64_advance_r + +#if PCG_HAS_128BIT_OPS + typedef struct pcg_state_128 pcg128si_random_t; +#define pcg128si_random_r pcg_oneseq_128_rxs_m_xs_128_random_r +#define pcg128si_boundedrand_r pcg_oneseq_128_rxs_m_xs_128_boundedrand_r +#define pcg128si_srandom_r pcg_oneseq_128_srandom_r +#define pcg128si_advance_r pcg_oneseq_128_advance_r +#endif + + //// Typedefs + typedef struct pcg_state_setseq_8 pcg8i_random_t; + typedef struct pcg_state_setseq_16 pcg16i_random_t; + typedef struct pcg_state_setseq_32 pcg32i_random_t; + typedef struct pcg_state_setseq_64 pcg64i_random_t; + //// random_r +#define pcg8i_random_r pcg_setseq_8_rxs_m_xs_8_random_r +#define pcg16i_random_r pcg_setseq_16_rxs_m_xs_16_random_r +#define pcg32i_random_r pcg_setseq_32_rxs_m_xs_32_random_r +#define pcg64i_random_r pcg_setseq_64_rxs_m_xs_64_random_r + //// boundedrand_r +#define pcg8i_boundedrand_r pcg_setseq_8_rxs_m_xs_8_boundedrand_r +#define pcg16i_boundedrand_r pcg_setseq_16_rxs_m_xs_16_boundedrand_r +#define pcg32i_boundedrand_r pcg_setseq_32_rxs_m_xs_32_boundedrand_r +#define pcg64i_boundedrand_r pcg_setseq_64_rxs_m_xs_64_boundedrand_r + //// srandom_r +#define pcg8i_srandom_r pcg_setseq_8_srandom_r +#define pcg16i_srandom_r pcg_setseq_16_srandom_r +#define pcg32i_srandom_r pcg_setseq_32_srandom_r +#define pcg64i_srandom_r pcg_setseq_64_srandom_r + //// advance_r +#define pcg8i_advance_r pcg_setseq_8_advance_r +#define pcg16i_advance_r pcg_setseq_16_advance_r +#define pcg32i_advance_r pcg_setseq_32_advance_r +#define pcg64i_advance_r pcg_setseq_64_advance_r + +#if PCG_HAS_128BIT_OPS + typedef struct pcg_state_setseq_128 pcg128i_random_t; +#define pcg128i_random_r pcg_setseq_128_rxs_m_xs_128_random_r +#define pcg128i_boundedrand_r pcg_setseq_128_rxs_m_xs_128_boundedrand_r +#define pcg128i_srandom_r pcg_setseq_128_srandom_r +#define pcg128i_advance_r pcg_setseq_128_advance_r +#endif + + extern uint32_t pcg32_random(); + extern uint32_t pcg32_boundedrand(uint32_t bound); + extern void pcg32_srandom(uint64_t seed, uint64_t seq); + extern void pcg32_advance(uint64_t delta); + +#if PCG_HAS_128BIT_OPS + extern uint64_t pcg64_random(); + extern uint64_t pcg64_boundedrand(uint64_t bound); + extern void pcg64_srandom(pcg128_t seed, pcg128_t seq); + extern void pcg64_advance(pcg128_t delta); +#endif + + /* + * Static initialization constants (if you can't call srandom for some + * bizarre reason). + */ + +#define PCG32_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER +#define PCG32U_INITIALIZER PCG_STATE_UNIQUE_64_INITIALIZER +#define PCG32S_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER +#define PCG32F_INITIALIZER PCG_STATE_MCG_64_INITIALIZER + +#if PCG_HAS_128BIT_OPS +#define PCG64_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER +#define PCG64U_INITIALIZER PCG_STATE_UNIQUE_128_INITIALIZER +#define PCG64S_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER +#define PCG64F_INITIALIZER PCG_STATE_MCG_128_INITIALIZER +#endif + +#if PCG_HAS_128BIT_OPS +#define PCG8SI_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER +#define PCG16SI_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER +#define PCG32SI_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER +#define PCG64SI_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER +#define PCG128SI_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER +#endif + +#if PCG_HAS_128BIT_OPS +#define PCG8I_INITIALIZER PCG_STATE_SETSEQ_8_INITIALIZER +#define PCG16I_INITIALIZER PCG_STATE_SETSEQ_16_INITIALIZER +#define PCG32I_INITIALIZER PCG_STATE_SETSEQ_32_INITIALIZER +#define PCG64I_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER +#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER +#endif + +#if __cplusplus +} +#endif + +#endif // PCG_VARIANTS_H_INCLUDED + diff --git a/src/haversine/listing_065.cpp b/src/haversine/listing_065.cpp new file mode 100644 index 0000000..86e087c --- /dev/null +++ b/src/haversine/listing_065.cpp @@ -0,0 +1,39 @@ +#include <math.h> + +static f64 Square(f64 A) +{ + f64 Result = (A*A); + return Result; +} + +static f64 RadiansFromDegrees(f64 Degrees) +{ + f64 Result = 0.01745329251994329577 * Degrees; + return Result; +} + +// NOTE(casey): EarthRadius is generally expected to be 6372.8 +static f64 ReferenceHaversine(f64 X0, f64 Y0, f64 X1, f64 Y1, f64 EarthRadius) +{ + /* NOTE(casey): This is not meant to be a "good" way to calculate the Haversine distance. + Instead, it attempts to follow, as closely as possible, the formula used in the real-world + question on which these homework exercises are loosely based. + */ + + f64 lat1 = Y0; + f64 lat2 = Y1; + f64 lon1 = X0; + f64 lon2 = X1; + + f64 dLat = RadiansFromDegrees(lat2 - lat1); + f64 dLon = RadiansFromDegrees(lon2 - lon1); + lat1 = RadiansFromDegrees(lat1); + lat2 = RadiansFromDegrees(lat2); + + f64 a = Square(sin(dLat/2.0)) + cos(lat1)*cos(lat2)*Square(sin(dLon/2)); + f64 c = 2.0*asin(sqrt(a)); + + f64 Result = EarthRadius * c; + + return Result; +} diff --git a/src/sim86/bin/generated/generated.cpp b/src/sim86/bin/generated/generated.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/sim86/bin/generated/generated.cpp diff --git a/src/tmux.sh b/src/sim86/bin/tmux.sh index 78845a9..78845a9 100755 --- a/src/tmux.sh +++ b/src/sim86/bin/tmux.sh diff --git a/src/build.sh b/src/sim86/build.sh index 7726aee..74f6828 100755 --- a/src/build.sh +++ b/src/sim86/build.sh @@ -1,9 +1,9 @@ #!/bin/sh -ThisDir="$(dirname "$(readlink -f "$0")")" -cd "$ThisDir" +cd "$(dirname "$(readlink -f "$0")")" -mkdir -p ../build +Build="../../build" +mkdir -p "$Build" mkdir -p generated Compiler="clang" @@ -30,12 +30,13 @@ WarningFlags=" printf '[metadata generation]\n' $Compiler $CompilerFlags $WarningFlags \ - -o ../build/sim86_meta \ + -o "$Build"/sim86_meta \ sim86_meta.c -../build/sim86_meta ./sim86.mdesk > ./generated/generated.cpp +"$Build"/sim86_meta ./sim86.mdesk > ./generated/generated.cpp +printf '[debug mode]\n' printf '[%s build]\n' "$Compiler" Source="sim86.cpp" $Compiler $CompilerFlags $WarningFlags \ - -o ../build/sim86 \ + -o "$Build"/sim86 \ sim86.cpp diff --git a/src/clocks_table.inl b/src/sim86/clocks_table.inl index 2c07bb3..2c07bb3 100644 --- a/src/clocks_table.inl +++ b/src/sim86/clocks_table.inl diff --git a/src/generated/generated.cpp b/src/sim86/generated/generated.cpp index 0f457a1..0f457a1 100644 --- a/src/generated/generated.cpp +++ b/src/sim86/generated/generated.cpp diff --git a/src/libs/metadesk/md.c b/src/sim86/libs/metadesk/md.c index 6be1e69..6be1e69 100644 --- a/src/libs/metadesk/md.c +++ b/src/sim86/libs/metadesk/md.c diff --git a/src/libs/metadesk/md.h b/src/sim86/libs/metadesk/md.h index faad8e3..faad8e3 100644 --- a/src/libs/metadesk/md.h +++ b/src/sim86/libs/metadesk/md.h diff --git a/src/libs/metadesk/md_stb_sprintf.h b/src/sim86/libs/metadesk/md_stb_sprintf.h index 4758435..4758435 100644 --- a/src/libs/metadesk/md_stb_sprintf.h +++ b/src/sim86/libs/metadesk/md_stb_sprintf.h diff --git a/src/libs/reference_decoder/sim86.h b/src/sim86/libs/reference_decoder/sim86.h index b065a0e..b065a0e 100644 --- a/src/libs/reference_decoder/sim86.h +++ b/src/sim86/libs/reference_decoder/sim86.h diff --git a/src/libs/reference_decoder/sim86_decode.cpp b/src/sim86/libs/reference_decoder/sim86_decode.cpp index dc084d5..dc084d5 100644 --- a/src/libs/reference_decoder/sim86_decode.cpp +++ b/src/sim86/libs/reference_decoder/sim86_decode.cpp diff --git a/src/libs/reference_decoder/sim86_decode.h b/src/sim86/libs/reference_decoder/sim86_decode.h index 534ce2d..534ce2d 100644 --- a/src/libs/reference_decoder/sim86_decode.h +++ b/src/sim86/libs/reference_decoder/sim86_decode.h diff --git a/src/libs/reference_decoder/sim86_instruction.cpp b/src/sim86/libs/reference_decoder/sim86_instruction.cpp index 34fcf1f..34fcf1f 100644 --- a/src/libs/reference_decoder/sim86_instruction.cpp +++ b/src/sim86/libs/reference_decoder/sim86_instruction.cpp diff --git a/src/libs/reference_decoder/sim86_instruction.h b/src/sim86/libs/reference_decoder/sim86_instruction.h index 191635a..191635a 100644 --- a/src/libs/reference_decoder/sim86_instruction.h +++ b/src/sim86/libs/reference_decoder/sim86_instruction.h diff --git a/src/libs/reference_decoder/sim86_instruction_table.cpp b/src/sim86/libs/reference_decoder/sim86_instruction_table.cpp index be3ec82..be3ec82 100644 --- a/src/libs/reference_decoder/sim86_instruction_table.cpp +++ b/src/sim86/libs/reference_decoder/sim86_instruction_table.cpp diff --git a/src/libs/reference_decoder/sim86_instruction_table.h b/src/sim86/libs/reference_decoder/sim86_instruction_table.h index ed8aea8..ed8aea8 100644 --- a/src/libs/reference_decoder/sim86_instruction_table.h +++ b/src/sim86/libs/reference_decoder/sim86_instruction_table.h diff --git a/src/libs/reference_decoder/sim86_instruction_table.inl b/src/sim86/libs/reference_decoder/sim86_instruction_table.inl index 576c0f6..576c0f6 100644 --- a/src/libs/reference_decoder/sim86_instruction_table.inl +++ b/src/sim86/libs/reference_decoder/sim86_instruction_table.inl diff --git a/src/libs/reference_decoder/sim86_lib.cpp b/src/sim86/libs/reference_decoder/sim86_lib.cpp index 6971eb2..6971eb2 100644 --- a/src/libs/reference_decoder/sim86_lib.cpp +++ b/src/sim86/libs/reference_decoder/sim86_lib.cpp diff --git a/src/libs/reference_decoder/sim86_memory.cpp b/src/sim86/libs/reference_decoder/sim86_memory.cpp index 1d58ede..1d58ede 100644 --- a/src/libs/reference_decoder/sim86_memory.cpp +++ b/src/sim86/libs/reference_decoder/sim86_memory.cpp diff --git a/src/libs/reference_decoder/sim86_memory.h b/src/sim86/libs/reference_decoder/sim86_memory.h index 4e790dc..4e790dc 100644 --- a/src/libs/reference_decoder/sim86_memory.h +++ b/src/sim86/libs/reference_decoder/sim86_memory.h diff --git a/src/libs/reference_decoder/sim86_text_table.cpp b/src/sim86/libs/reference_decoder/sim86_text_table.cpp index e90a649..e90a649 100644 --- a/src/libs/reference_decoder/sim86_text_table.cpp +++ b/src/sim86/libs/reference_decoder/sim86_text_table.cpp diff --git a/src/sim86.cpp b/src/sim86/sim86.cpp index 7c444bd..7c444bd 100644 --- a/src/sim86.cpp +++ b/src/sim86/sim86.cpp diff --git a/src/sim86.h b/src/sim86/sim86.h index 24068e2..24068e2 100644 --- a/src/sim86.h +++ b/src/sim86/sim86.h diff --git a/src/sim86.mdesk b/src/sim86/sim86.mdesk index 0635110..0635110 100644 --- a/src/sim86.mdesk +++ b/src/sim86/sim86.mdesk diff --git a/src/sim86_meta.c b/src/sim86/sim86_meta.c index c8fe8f3..37fe0c3 100644 --- a/src/sim86_meta.c +++ b/src/sim86/sim86_meta.c @@ -1,3 +1,4 @@ + #if __clang__ # define COMPILER_CLANG 1 #elif _MSC_VER diff --git a/src/sim86_shared.h b/src/sim86/sim86_shared.h index 7a54beb..7a54beb 100644 --- a/src/sim86_shared.h +++ b/src/sim86/sim86_shared.h |
