├── .cirrus.yml ├── .coveragerc ├── .gitattributes ├── .github └── workflows │ ├── codeql.yml │ ├── cron-build-and-test.yml │ └── generate-documentation.yml ├── .gitignore ├── .pep8speaks.yml ├── LICENSE.md ├── MANIFEST.in ├── README.md ├── azure-pipelines.yml ├── benchmark.py ├── ci ├── azure │ ├── azure_template_posix.yml │ ├── azure_template_windows.yml │ ├── install-posix.sh │ └── update_path.sh ├── cirrus │ └── cirrus-install-arm.sh └── github-actions │ └── push-docs-gh-pages.sh ├── codecov.yml ├── doc ├── Makefile ├── make.bat ├── requirements.txt └── source │ ├── _static │ └── images │ │ └── favicon.ico │ ├── bit_generators │ ├── aesctr.rst │ ├── chacha.rst │ ├── dsfmt.rst │ ├── efiix64.rst │ ├── hc128.rst │ ├── index.rst │ ├── jsf.rst │ ├── lcg128mix.rst │ ├── lxm.rst │ ├── mt19937.rst │ ├── mt64.rst │ ├── pcg32.rst │ ├── pcg64.rst │ ├── pcg64dxsm.rst │ ├── philox.rst │ ├── rdrand.rst │ ├── romu.rst │ ├── sfc.rst │ ├── sfmt.rst │ ├── speck128.rst │ ├── squares.rst │ ├── threefry.rst │ ├── tyche.rst │ ├── userbitgenerator.rst │ ├── xoroshiro128.rst │ ├── xorshift1024.rst │ ├── xoshiro256.rst │ └── xoshiro512.rst │ ├── change-log.rst │ ├── conf.py │ ├── custom-bit-generators.ipynb │ ├── entropy.rst │ ├── evolution.rst │ ├── extended-generator.rst │ ├── extending.rst │ ├── future.rst │ ├── generator.rst │ ├── images │ ├── casino.svg │ └── favicon.ico │ ├── index.rst │ ├── legacy.rst │ ├── multithreading.rst │ ├── names_wordlist.txt │ ├── new-or-different.rst │ ├── parallel.rst │ ├── performance.py │ ├── performance.rst │ ├── references.rst │ ├── savefig │ └── .empty-folder │ ├── seed_sequence.rst │ ├── spelling_wordlist.txt │ ├── test-results.txt │ └── testing.rst ├── pyproject.toml ├── randomgen ├── __init__.py ├── _deprecated_value.py ├── _pickle.py ├── _register.py ├── _seed_sequence.pxd ├── _seed_sequence.pyi ├── _seed_sequence.pyx ├── aes.pxd ├── aes.pyi ├── aes.pyx ├── api.pxd ├── bounded_integers.pxd.in ├── bounded_integers.pyx.in ├── broadcasting.pxd ├── broadcasting.pyx ├── chacha.pxd ├── chacha.pyi ├── chacha.pyx ├── common.pxd ├── common.pyi ├── common.pyx ├── conftest.py ├── distributions.pxd ├── dsfmt.pxd ├── dsfmt.pyi ├── dsfmt.pyx ├── efiix64.pxd ├── efiix64.pyi ├── efiix64.pyx ├── entropy.pyi ├── entropy.pyx ├── examples │ ├── cython │ │ ├── extending.pyx │ │ ├── extending_distributions.pyx │ │ ├── low_level.pyx │ │ └── setup.py │ └── numba │ │ ├── extending.py │ │ └── extending_distributions.py ├── generator.pyi ├── generator.pyx ├── hc128.pxd ├── hc128.pyi ├── hc128.pyx ├── jsf.pxd ├── jsf.pyi ├── jsf.pyx ├── legacy │ ├── __init__.py │ ├── bounded_integers.pxd.in │ ├── bounded_integers.pyx.in │ └── distributions.pxd ├── lxm.pxd ├── lxm.pyi ├── lxm.pyx ├── mt19937.pxd ├── mt19937.pyi ├── mt19937.pyx ├── mt64.pxd ├── mt64.pyi ├── mt64.pyx ├── mtrand.pyi ├── mtrand.pyx ├── pcg32.pxd ├── pcg32.pyi ├── pcg32.pyx ├── pcg64.pxd ├── pcg64.pyi ├── pcg64.pyx ├── philox.pxd ├── philox.pxd.in ├── philox.pyi ├── philox.pyx ├── py.typed ├── rdrand.pxd ├── rdrand.pyi ├── rdrand.pyx ├── romu.pxd ├── romu.pyi ├── romu.pyx ├── seed_sequence.py ├── sfc.pxd ├── sfc.pyi ├── sfc.pyx ├── sfmt.pxd ├── sfmt.pyi ├── sfmt.pyx ├── speck128.pxd ├── speck128.pyi ├── speck128.pyx ├── squares.pxd ├── squares.pyx ├── src │ ├── aesctr │ │ ├── LICENSE.md │ │ ├── aesctr-test-data-gen.c │ │ ├── aesctr.c │ │ ├── aesctr.h │ │ ├── aesctr.orig.h │ │ ├── softaes.h │ │ ├── tiny-aes.c │ │ └── tiny-aes.h │ ├── aligned_malloc │ │ ├── aligned_malloc.c │ │ └── aligned_malloc.h │ ├── chacha │ │ ├── LICENSE.md │ │ ├── chacha-benchmark.cpp │ │ ├── chacha-test-data-gen.cpp │ │ ├── chacha-v1.c │ │ ├── chacha.c │ │ ├── chacha.h │ │ └── chacha.orig.h │ ├── common │ │ ├── LICENSE.md │ │ ├── array.h │ │ ├── cpu_features.c │ │ ├── cpu_features.h │ │ ├── features │ │ │ ├── clangfeatures.h │ │ │ ├── compilerfeatures.h │ │ │ ├── gccfeatures.h │ │ │ ├── iccfeatures.h │ │ │ ├── metalfeatures.h │ │ │ ├── msvcfeatures.h │ │ │ ├── nvccfeatures.h │ │ │ ├── open64features.h │ │ │ ├── openclfeatures.h │ │ │ ├── pgccfeatures.h │ │ │ ├── sse.h │ │ │ ├── sunprofeatures.h │ │ │ └── xlcfeatures.h │ │ ├── inttypes.h │ │ ├── randomgen_config.h │ │ ├── randomgen_config_numpy.h │ │ ├── randomgen_endian.h │ │ ├── randomgen_immintrin.h │ │ ├── standalone │ │ │ ├── Python.h │ │ │ ├── aligned_malloc.h │ │ │ ├── npy_common.h │ │ │ └── npy_math.h │ │ ├── stdbool.h │ │ └── stdint.h │ ├── distributions │ │ ├── LICENSE.md │ │ ├── binomial.h │ │ ├── distributions.orig.c │ │ ├── distributions.orig.h │ │ ├── hypergeometric.c │ │ ├── logfactorial.c │ │ ├── logfactorial.h │ │ ├── loggam.h │ │ ├── rg-distributions.c │ │ ├── rg-distributions.h │ │ ├── ziggurat.h │ │ └── ziggurat_constants.h │ ├── dsfmt │ │ ├── 128-bit-jump.poly.txt │ │ ├── 96-bit-jump.poly.txt │ │ ├── LICENSE.md │ │ ├── calc-jump.cpp │ │ ├── dSFMT-benchmark.c │ │ ├── dSFMT-calc-jump.hpp │ │ ├── dSFMT-common.h │ │ ├── dSFMT-jump.c │ │ ├── dSFMT-jump.h │ │ ├── dSFMT-params.h │ │ ├── dSFMT-params19937.h │ │ ├── dSFMT-poly.h │ │ ├── dSFMT-test-gen.c │ │ ├── dsfmt-test-data-seed.h │ │ ├── dsfmt.c │ │ └── dsfmt.h │ ├── efiix64 │ │ ├── efiix64-test-gen.cpp │ │ ├── efiix64.c │ │ └── efiix64.h │ ├── entropy │ │ ├── LICENSE.md │ │ ├── entropy.c │ │ └── entropy.h │ ├── hc-128 │ │ ├── hc-128-test-data-gen.c │ │ ├── hc-128.c │ │ ├── hc-128.h │ │ ├── hc-128.orig.c │ │ ├── hc-128.orig.h │ │ ├── hc128_ref.h │ │ ├── util.orig.c │ │ └── util.orig.h │ ├── jsf │ │ ├── jsf-test-data-gen.cpp │ │ ├── jsf.c │ │ ├── jsf.h │ │ └── jsf.hpp │ ├── legacy │ │ ├── LICENSE.md │ │ ├── legacy-distributions.c │ │ └── legacy-distributions.h │ ├── lxm │ │ ├── lxm-test-data-gen.c │ │ ├── lxm.c │ │ └── lxm.h │ ├── mt19937 │ │ ├── LICENSE.md │ │ ├── clist_mt19937.txt │ │ ├── generate-jump-test.py │ │ ├── jump_mt19937-orig.c │ │ ├── jump_mt19937.c │ │ ├── mt119937-test-data-seed.h │ │ ├── mt19937-benchmark.c │ │ ├── mt19937-generate-jump-poly.c │ │ ├── mt19937-jump.c │ │ ├── mt19937-jump.h │ │ ├── mt19937-poly.h │ │ ├── mt19937-test-data-gen.c │ │ ├── mt19937.c │ │ ├── mt19937.h │ │ ├── poly-128.txt │ │ ├── randomkit.c │ │ └── randomkit.h │ ├── mt64 │ │ ├── mt64-test-data-gen.c │ │ ├── mt64-test-data-seed.h │ │ ├── mt64.c │ │ ├── mt64.h │ │ ├── mt64.orig.c │ │ └── mt64.orig.h │ ├── pcg32 │ │ ├── LICENSE.md │ │ ├── pcg-advance-64.c │ │ ├── pcg32-test-data-gen.c │ │ ├── pcg32.c │ │ ├── pcg32.h │ │ └── pcg_variants.h │ ├── pcg64 │ │ ├── LICENSE.md │ │ ├── lcg128mix.c │ │ ├── lcg128mix.h │ │ ├── pcg64-benchmark.c │ │ ├── pcg64-common.c │ │ ├── pcg64-common.h │ │ ├── pcg64-test-data-gen.c │ │ ├── pcg64-v2.c │ │ ├── pcg64-v2.h │ │ ├── pcg64.c │ │ ├── pcg64.h │ │ ├── pcg64.orig.c │ │ ├── pcg64.orig.h │ │ ├── pcg64_xslrr-test-data-gen.cpp │ │ ├── pcg_dxsm-test-data-gen.cpp │ │ ├── pcg_extras.hpp │ │ ├── pcg_random.hpp │ │ ├── pcg_uint128.hpp │ │ └── pcg_xslrr-test-data-gen.cpp │ ├── philox │ │ ├── LICENSE.md │ │ ├── philox-4x32-test-data-gen.c │ │ ├── philox-benchmark.c │ │ ├── philox-test-data-gen.c │ │ ├── philox.c │ │ └── philox.h │ ├── rdrand │ │ ├── rdrand.c │ │ └── rdrand.h │ ├── romu │ │ ├── romu-orig.h │ │ ├── romu-test-data-gen.c │ │ ├── romu.c │ │ └── romu.h │ ├── sfc │ │ ├── sfc-test-data-gen.c │ │ ├── sfc.c │ │ └── sfc.h │ ├── sfmt │ │ ├── SFMT-calc-jump.hpp │ │ ├── calc-jump.cpp │ │ ├── sfmt-alti.h │ │ ├── sfmt-common.h │ │ ├── sfmt-jump.c │ │ ├── sfmt-jump.h │ │ ├── sfmt-neon.h │ │ ├── sfmt-params.h │ │ ├── sfmt-params19937.h │ │ ├── sfmt-poly.h │ │ ├── sfmt-sse2-msc.h │ │ ├── sfmt-sse2.h │ │ ├── sfmt-test-data-seed.h │ │ ├── sfmt-test-gen.c │ │ ├── sfmt.c │ │ └── sfmt.h │ ├── speck-128 │ │ ├── speck-128-common.h │ │ ├── speck-128-sse.h │ │ ├── speck-128.c │ │ ├── speck-128.h │ │ ├── speck-128.ref.c │ │ └── speck-test-data-gen.cpp │ ├── splitmix64 │ │ ├── LICENSE.md │ │ ├── splitmix64.c │ │ ├── splitmix64.h │ │ └── splitmix64.orig.c │ ├── squares │ │ ├── squares-test-data-gen.c │ │ ├── squares.c │ │ ├── squares.h │ │ ├── squares.orig.h │ │ └── squares.py │ ├── threefry │ │ ├── LICENSE.md │ │ ├── threefry-benchmark.c │ │ ├── threefry-orig.c │ │ ├── threefry-test-data-gen.c │ │ ├── threefry.c │ │ ├── threefry.h │ │ └── threefry4x32-test-data-gen.c │ ├── tyche │ │ ├── base_state.h │ │ ├── tyche-gen-test-data.cpp │ │ ├── tyche.c │ │ ├── tyche.h │ │ ├── tyche.orig.h │ │ └── util.h │ ├── xoroshiro128 │ │ ├── LICENSE.md │ │ ├── xoroshiro128-benchmark.c │ │ ├── xoroshiro128-test-data-gen.c │ │ ├── xoroshiro128.c │ │ ├── xoroshiro128.h │ │ ├── xoroshiro128plus.orig.c │ │ ├── xoroshiro128plus.orig.h │ │ ├── xoroshiro128plusplus-test-data-gen.c │ │ └── xoroshiro128plusplus.orig.c │ ├── xorshift1024 │ │ ├── LICENSE.md │ │ ├── xorshift1024-benchmark.c │ │ ├── xorshift1024-test-data-gen.c │ │ ├── xorshift1024.c │ │ ├── xorshift1024.h │ │ ├── xorshift1024.orig.c │ │ └── xorshift1024.orig.h │ ├── xoshiro256 │ │ ├── LICENSE.md │ │ ├── xoshiro256-benchmark-indirect.c │ │ ├── xoshiro256-benchmark.c │ │ ├── xoshiro256-test-data-gen.c │ │ ├── xoshiro256.c │ │ ├── xoshiro256.h │ │ ├── xoshiro256.orig.c │ │ └── xoshiro256.orig.h │ └── xoshiro512 │ │ ├── LICENSE.md │ │ ├── xoshiro512-test-data-gen.c │ │ ├── xoshiro512.c │ │ ├── xoshiro512.h │ │ ├── xoshiro512.orig.c │ │ └── xoshiro512.orig.h ├── tests │ ├── __init__.py │ ├── _shim_dist.c │ ├── _shim_dist.h │ ├── _shims.pxd │ ├── _shims.pyi │ ├── _shims.pyx │ ├── data │ │ ├── __init__.py │ │ ├── _write_hashes.py │ │ ├── aesctr-testset-1.csv │ │ ├── aesctr-testset-2.csv │ │ ├── chacha-testset-1.csv │ │ ├── chacha-testset-2.csv │ │ ├── compute_hashes.py │ │ ├── ctypes_testing.c │ │ ├── dSFMT-testset-1.csv │ │ ├── dSFMT-testset-2.csv │ │ ├── efiix64-testset-1.csv │ │ ├── efiix64-testset-2.csv │ │ ├── hc-128-testset-1.csv │ │ ├── hc-128-testset-2.csv │ │ ├── jsf32-testset-1.csv │ │ ├── jsf32-testset-2.csv │ │ ├── jsf64-testset-1.csv │ │ ├── jsf64-testset-2.csv │ │ ├── lxm-testset-1.csv │ │ ├── lxm-testset-2.csv │ │ ├── mt19937-testset-1.csv │ │ ├── mt19937-testset-2.csv │ │ ├── mt64-testset-1.csv │ │ ├── mt64-testset-2.csv │ │ ├── pcg32-testset-1.csv │ │ ├── pcg32-testset-2.csv │ │ ├── pcg64-cm-dxsm-testset-1.csv │ │ ├── pcg64-cm-dxsm-testset-2.csv │ │ ├── pcg64-cm-xsl_rr-testset-1.csv │ │ ├── pcg64-cm-xsl_rr-testset-2.csv │ │ ├── pcg64-dxsm-testset-1.csv │ │ ├── pcg64-dxsm-testset-2.csv │ │ ├── pcg64-testset-1.csv │ │ ├── pcg64-testset-2.csv │ │ ├── pcg64-xsl_rr-testset-1.csv │ │ ├── pcg64-xsl_rr-testset-2.csv │ │ ├── philox-testset-1.csv │ │ ├── philox-testset-2.csv │ │ ├── philox4x32-testset-1.csv │ │ ├── philox4x32-testset-2.csv │ │ ├── romuquad-testset-1.csv │ │ ├── romuquad-testset-2.csv │ │ ├── romutrio-testset-1.csv │ │ ├── romutrio-testset-2.csv │ │ ├── sfc-testset-1.csv │ │ ├── sfc-testset-2.csv │ │ ├── sfmt-testset-1.csv │ │ ├── sfmt-testset-2.csv │ │ ├── speck-128-testset-1.csv │ │ ├── speck-128-testset-2.csv │ │ ├── squares-32-testset-1.csv │ │ ├── squares-32-testset-2.csv │ │ ├── squares-testset-1.csv │ │ ├── squares-testset-2.csv │ │ ├── stability_results.py │ │ ├── stable_hashes.py │ │ ├── threefry-testset-1.csv │ │ ├── threefry-testset-2.csv │ │ ├── threefry32-testset-1.csv │ │ ├── threefry32-testset-2.csv │ │ ├── tyche-openrand-testset-1.csv │ │ ├── tyche-openrand-testset-2.csv │ │ ├── tyche-testset-1.csv │ │ ├── tyche-testset-2.csv │ │ ├── xoroshiro128-testset-1.csv │ │ ├── xoroshiro128-testset-2.csv │ │ ├── xoroshiro128plusplus-testset-1.csv │ │ ├── xoroshiro128plusplus-testset-2.csv │ │ ├── xorshift1024-testset-1.csv │ │ ├── xorshift1024-testset-2.csv │ │ ├── xoshiro256-testset-1.csv │ │ ├── xoshiro256-testset-2.csv │ │ ├── xoshiro512-testset-1.csv │ │ └── xoshiro512-testset-2.csv │ ├── test_bit_generators_against_numpy.py │ ├── test_broadcasting.py │ ├── test_common.py │ ├── test_direct.py │ ├── test_extended_generator.py │ ├── test_final_release_changes.py │ ├── test_generator_mt19937.py │ ├── test_lcg128mix_pcg64dxsm.py │ ├── test_seed_sequence.py │ ├── test_sfc.py │ ├── test_smoke.py │ ├── test_stability.py │ ├── test_wrapper.py │ └── test_wrapper_numba.py ├── threefry.pxd ├── threefry.pxd.in ├── threefry.pyi ├── threefry.pyx ├── tyche.pxd ├── tyche.pyi ├── tyche.pyx ├── typing.py ├── wrapper.pyi ├── wrapper.pyx ├── xoroshiro128.pxd ├── xoroshiro128.pyi ├── xoroshiro128.pyx ├── xorshift1024.pxd ├── xorshift1024.pyi ├── xorshift1024.pyx ├── xoshiro256.pxd ├── xoshiro256.pyi ├── xoshiro256.pyx ├── xoshiro512.pxd ├── xoshiro512.pyi └── xoshiro512.pyx ├── requirements-dev.txt ├── requirements.txt ├── setup.cfg ├── setup.py └── tools ├── configuration.py ├── long_double_sizes.c ├── practrand-driver-config.py ├── practrand-driver.py ├── prng-tester.py ├── process-prng-tester-results.py ├── results ├── results-entropy-0.json ├── results-seed-correlation.json ├── results-sequential-seed.json └── results.json ├── shared.py ├── templates ├── configuration.jinja └── seed-correlation.jinja └── test-seed-correlation.py /.cirrus.yml: -------------------------------------------------------------------------------- 1 | linux_arm_task: 2 | name: Linux-ARM 3 | arm_container: {image: python:slim} 4 | install_script: . ./ci/cirrus/cirrus-install-arm.sh 5 | test_script: mkdir test_dir && cd test_dir && echo $PWD && python3 -c "import randomgen; randomgen.test(['-n', '2'])" 6 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | # .coveragerc to control coverage.py 2 | [run] 3 | branch = True 4 | include = */randomgen/* 5 | omit = 6 | */_version.py 7 | *.pxd 8 | */_write_hashes.py 9 | plugins = Cython.Coverage 10 | 11 | [report] 12 | # Regexes for lines to exclude from consideration 13 | exclude_lines = 14 | # Have to re-enable the standard pragma 15 | pragma: no cover 16 | 17 | # Don't complain if tests don't hit defensive assertion code: 18 | raise NotImplementedError 19 | except NotImplementedError 20 | except RuntimeError 21 | raise NotImplemented\(\"subclasses must implement\"\) 22 | # Ignore pass 23 | pass 24 | # Ignore failure messages 25 | pytest.xfail 26 | # Ignore ImportError protection 27 | except ImportError 28 | raise ImportError 29 | # Cython function declarations 30 | cdef 31 | cdef inline 32 | ctypedef 33 | # Ignore dummy thread 34 | from dummy_threading import Lock 35 | 36 | include = */randomgen/* 37 | omit = 38 | */_version.py 39 | ignore_errors = True 40 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | randomgen/_version.py export-subst 2 | * text=auto eol=lf 3 | -------------------------------------------------------------------------------- /.github/workflows/cron-build-and-test.yml: -------------------------------------------------------------------------------- 1 | name: Build wheels 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | schedule: 9 | - cron: '37 0 * * 2' # 2/weekly 10 | 11 | jobs: 12 | build_wheels: 13 | name: ${{ matrix.os }}, Python ${{ matrix.python }} 14 | runs-on: ${{ matrix.os }} 15 | defaults: 16 | run: 17 | shell: bash 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | python: [cp312] 22 | os: [ubuntu-latest, windows-latest, macos-latest, macos-13] 23 | env: 24 | BUILD_COMMIT: "main" 25 | CIBW_BUILD: ${{ matrix.python }}-* 26 | CIBW_ARCHS_LINUX: "x86_64" 27 | CIBW_ARCHS_MACOS: "auto" 28 | CIBW_SKIP: "pp* *-musllinux_* *-win32" 29 | CIBW_TEST_REQUIRES: pytest pytest-xdist 30 | CIBW_TEST_COMMAND: python -c "import randomgen; randomgen.test(['--skip-slow','-n','2'])" 31 | CIBW_REPAIR_WHEEL_COMMAND_LINUX: 'auditwheel repair --strip -w {dest_dir} {wheel}' 32 | MKL_NUM_THREADS: 1 33 | OMP_NUM_THREADS: 1 34 | OPENLAS_NUM_THREADS: 1 35 | 36 | steps: 37 | - uses: actions/checkout@v4 38 | 39 | - name: Build wheels 40 | uses: pypa/cibuildwheel@v2.21 41 | with: 42 | output-dir: wheelhouse 43 | -------------------------------------------------------------------------------- /.github/workflows/generate-documentation.yml: -------------------------------------------------------------------------------- 1 | name: Generate Documentation 2 | 3 | on: 4 | release: 5 | types: [published] 6 | push: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | defaults: 14 | run: 15 | shell: bash 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | python-version: ["3.11"] 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 25 | - name: Install pandoc 26 | uses: r-lib/actions/setup-pandoc@v2 27 | - name: Set up Python ${{ matrix.python-version }} 28 | uses: actions/setup-python@v5 29 | with: 30 | python-version: ${{ matrix.python-version }} 31 | - name: Install dependencies 32 | run: | 33 | python -m pip install --upgrade pip wheel setuptools>=61 34 | python -m pip install -r requirements.txt 35 | python -m pip install -r requirements-dev.txt 36 | python -m pip install -r doc/requirements.txt 37 | python -m pip list 38 | - name: Install randomgen 39 | run: python -m pip install -e . --no-build-isolation -v 40 | - name: Build documentation 41 | run: | 42 | echo "PWD: ${PWD}" 43 | pushd doc 44 | make html 45 | make html 46 | popd 47 | echo "PWD: ${PWD}" 48 | - name: Deploy documentation 49 | env: 50 | GIT_TAG: ${{ github.event.release.tag_name }} 51 | run: source ci/github-actions/push-docs-gh-pages.sh 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .hypothesis/ 2 | .idea/ 3 | .vscode/ 4 | build/ 5 | *.egg-info/ 6 | *.pyd 7 | *.pyc 8 | *.html 9 | *.obj 10 | *.exe 11 | **/Random123 12 | settings.json 13 | *.so 14 | randomgen/_version.py 15 | randomgen/bounded_integers.pyx 16 | randomgen/bounded_integers.pxd 17 | randomgen/*.c 18 | randomgen/tests/*.c 19 | randomgen/legacy/bounded_integers.c 20 | randomgen/legacy/bounded_integers.pyx 21 | randomgen/legacy/bounded_integers.pxd 22 | doc/build 23 | doc/**/generated 24 | -------------------------------------------------------------------------------- /.pep8speaks.yml: -------------------------------------------------------------------------------- 1 | scanner: 2 | diff_only: False 3 | linter: pycodestyle # Other option is flake8 4 | 5 | pycodestyle: # Same as scanner.linter value. Other option is flake8 6 | max-line-length: 99 # Default is 79 in PEP 8 7 | ignore: # Errors and warnings to ignore 8 | - E203 # Whitespace before ':' 9 | - W503 # Line break occurred before a binary operator (W503) 10 | - E301 11 | - E302 12 | - E305 13 | - E501 14 | - E701 15 | 16 | no_blank_comment: False # If True, no comment is made on PR without any errors. 17 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-exclude randomgen *.c 2 | include randomgen/py.typed 3 | include randomgen/_version.py 4 | include requirements.txt 5 | include README.md 6 | include LICENSE.md 7 | recursive-include randomgen *.py *.pyx *.px[di] *.h *.in *.csv *.md 8 | graft randomgen/src 9 | include randomgen/tests/_shim_dist.h 10 | include randomgen/tests/_shim_dist.c 11 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops#passing-parameters 2 | schedules: 3 | - cron: "27 3 * * 0" 4 | # 3:27am UTC every Sunday 5 | displayName: Weekly build 6 | branches: 7 | include: 8 | - main 9 | always: true 10 | 11 | trigger: 12 | - main 13 | 14 | variables: 15 | PYTHONHASHSEED: 12345678 16 | coverage: true 17 | RANDOMGEN_CYTHON_COVERAGE: true 18 | 19 | jobs: 20 | - template: ci/azure/azure_template_posix.yml 21 | parameters: 22 | name: macOS 23 | vmImage: macOS-latest 24 | 25 | - template: ci/azure/azure_template_posix.yml 26 | parameters: 27 | name: Linux 28 | vmImage: ubuntu-latest 29 | 30 | - template: ci/azure/azure_template_windows.yml 31 | parameters: 32 | name: Windows 33 | vmImage: windows-latest 34 | -------------------------------------------------------------------------------- /ci/azure/azure_template_windows.yml: -------------------------------------------------------------------------------- 1 | # Python package 2 | # Create and test a Python package on multiple Python versions. 3 | # Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/python 5 | 6 | parameters: 7 | # defaults for any parameters that are not specified 8 | name: '' 9 | vmImage: '' 10 | 11 | 12 | jobs: 13 | 14 | - job: ${{ parameters.name }}Test 15 | pool: 16 | vmImage: ${{ parameters.vmImage }} 17 | strategy: 18 | matrix: 19 | python39_win_latest: 20 | python.version: '3.9' 21 | python310_win_latest: 22 | python.version: '3.10' 23 | python311_win_latest: 24 | python.version: '3.11' 25 | python312_win_latest: 26 | python.version: '3.12' 27 | maxParallel: 10 28 | 29 | steps: 30 | - task: UsePythonVersion@0 31 | inputs: 32 | versionSpec: '$(python.version)' 33 | architecture: 'x64' 34 | displayName: 'Use Python $(python.version)' 35 | 36 | - script: | 37 | python -m pip install --upgrade pip setuptools wheel 38 | python -m pip install -r requirements.txt 39 | python -m pip install -r requirements-dev.txt 40 | displayName: 'Install dependencies' 41 | 42 | - script: | 43 | python -m pip list 44 | displayName: 'List Configuration' 45 | 46 | - script: | 47 | python -m pip install -e . -v --no-build-isolation 48 | displayName: 'Build Cython Extensions' 49 | 50 | - script: | 51 | pytest randomgen --junitxml=junit/test-results.xml --durations=25 -v 52 | displayName: 'pytest' 53 | 54 | - task: PublishTestResults@2 55 | inputs: 56 | testResultsFiles: '**/test-results.xml' 57 | testRunTitle: 'Python $(python.version)' 58 | condition: succeededOrFailed() 59 | -------------------------------------------------------------------------------- /ci/azure/install-posix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ ${USE_CONDA} == "true" ]]; then 4 | conda config --set always_yes true 5 | conda update --all --quiet 6 | conda create -n randomgen-test python=${PYTHON_VERSION} -y 7 | conda init 8 | source activate randomgen-test 9 | which python 10 | CMD="conda install numpy" 11 | else 12 | CMD="python -m pip install cffi numpy" 13 | fi 14 | 15 | # Not all available in conda 16 | python -m pip install setuptools "setuptools_scm[toml]>=8,<9" wheel pip black==24.8.0 isort flake8 threadpoolctl --upgrade 17 | 18 | EXTRA="pytest pytest-xdist coverage pytest-cov colorama" 19 | 20 | if [[ -n ${NUMPY} ]]; then CMD="$CMD~=${NUMPY}"; fi; 21 | CMD="$CMD cython" 22 | if [[ -n ${CYTHON} ]]; then CMD="$CMD~=${CYTHON}"; fi; 23 | CMD="$CMD pandas" 24 | CMD="$CMD $EXTRA" 25 | if [[ ${USE_CONDA} == "true" ]]; then CMD="$CMD numba"; fi; 26 | if [[ ${USE_SCIPY} == "true" ]]; then CMD="$CMD scipy"; fi; 27 | if [[ ${USE_NUMBA} == "true" ]]; then CMD="$CMD numba==$NUMBA"; fi; 28 | echo $CMD 29 | eval $CMD 30 | 31 | 32 | if [ "${PIP_PRE}" = true ]; then 33 | python -m pip uninstall -y numpy pandas scipy 34 | python -m pip install -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy pandas scipy --upgrade --use-deprecated=legacy-resolver 35 | fi 36 | -------------------------------------------------------------------------------- /ci/azure/update_path.sh: -------------------------------------------------------------------------------- 1 | if [[ ${USE_CONDA} == "true" ]]; then 2 | source activate randomgen-test 3 | fi -------------------------------------------------------------------------------- /ci/cirrus/cirrus-install-arm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | apt-get update -y 4 | apt-get install build-essential git -y 5 | python3 -m ensurepip --upgrade 6 | python3 -m pip install --upgrade --upgrade pip setuptools wheel pytest pytest-xdist packaging 7 | python3 -m pip install -r requirements.txt 8 | python3 -m pip install -r requirements-dev.txt 9 | python3 -m pip list 10 | git fetch --tags 11 | python3 -m pip install . --no-build-isolation -vv 12 | python3 -m pip list 13 | -------------------------------------------------------------------------------- /ci/github-actions/push-docs-gh-pages.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export GIT_REPO_DIR=${PWD} 4 | echo "Set git email and name" 5 | git config user.email "kevin.k.sheppard@gmail.com" 6 | git config user.name "Kevin Sheppard" 7 | git config advice.addIgnoredFile false 8 | echo "Dry run for clean" 9 | git clean -dfn 10 | echo "Checkout pages" 11 | git checkout gh-pages --force 12 | echo "Remove devel" 13 | rm -rf devel 14 | echo "Make a new devel" 15 | mkdir devel 16 | echo "Checking for tag" 17 | if [[ -n "${GIT_TAG}" ]]; then 18 | echo "Tag ${GIT_TAG} is defined" 19 | echo "Copy docs to root" 20 | echo cp -r ${PWD}/doc/build/html/* ${PWD}/ 21 | cp -r ${PWD}/doc/build/html/* ${PWD} 22 | else 23 | echo "Tag is ${GIT_TAG}. Not updating main documents" 24 | fi 25 | echo "Copy docs to devel" 26 | echo cp -r ${PWD}/doc/build/html/* ${PWD}/devel/ 27 | cp -r ${PWD}/doc/build/html/* ${PWD}/devel/ 28 | echo "Clean up docs" 29 | cd ${GIT_REPO_DIR}/doc 30 | make clean && git clean -xfd 31 | echo "Add files" 32 | cd ${GIT_REPO_DIR} 33 | git add . 34 | # Ensure key files are added 35 | git add devel/**/* || true 36 | git add **/*.html || true 37 | git add **/*.ipynb || true 38 | git add **/*.txt || true 39 | git add _images/* || true 40 | git add _sources/**/* || true 41 | git add _modules/**/* || true 42 | git add _static/**/* || true 43 | echo "Change remote" 44 | git remote set-url origin https://bashtage:"${GITHUB_TOKEN}"@github.com/bashtage/randomgen.git 45 | echo "Github Actions doc build after commit ${GITHUB_SHA::8}" 46 | git commit -a -m "Github Actions doc build after commit ${GITHUB_SHA::8}" 47 | echo "Push" 48 | git push -f 49 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | branch: main 3 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = RandomGen 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /doc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | set SPHINXPROJ=RandomGen 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.https://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | numba>=0.49 2 | nbsphinx 3 | sphinx-immaterial 4 | sphinx>=8 5 | ipython>=8 6 | pickleshare 7 | pygments>=2.7.4 # not directly required, pinned by Snyk to avoid a vulnerability 8 | -------------------------------------------------------------------------------- /doc/source/_static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bashtage/randomgen/34bc41ac41b94a0df9806fdd4ed242531b520e3a/doc/source/_static/images/favicon.ico -------------------------------------------------------------------------------- /doc/source/bit_generators/aesctr.rst: -------------------------------------------------------------------------------- 1 | AES Counter-based RNG 2 | --------------------- 3 | 4 | .. module:: randomgen.aes 5 | 6 | .. currentmodule:: randomgen.aes 7 | 8 | .. autoclass:: AESCounter 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~AESCounter.seed 17 | ~AESCounter.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~AESCounter.advance 25 | ~AESCounter.jump 26 | ~AESCounter.jumped 27 | 28 | Extending 29 | ========= 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | ~AESCounter.cffi 34 | ~AESCounter.ctypes 35 | 36 | Testing 37 | ======= 38 | .. autosummary:: 39 | :toctree: generated/ 40 | 41 | ~AESCounter.random_raw 42 | -------------------------------------------------------------------------------- /doc/source/bit_generators/chacha.rst: -------------------------------------------------------------------------------- 1 | ChaCha Cipher-based RNG 2 | ----------------------- 3 | 4 | .. module:: randomgen.chacha 5 | 6 | .. currentmodule:: randomgen.chacha 7 | 8 | .. autoclass:: ChaCha 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~ChaCha.seed 17 | ~ChaCha.state 18 | 19 | Extending 20 | ========= 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~ChaCha.cffi 25 | ~ChaCha.ctypes 26 | 27 | Testing 28 | ======= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~ChaCha.random_raw 33 | -------------------------------------------------------------------------------- /doc/source/bit_generators/dsfmt.rst: -------------------------------------------------------------------------------- 1 | Double SIMD Mersenne Twister (dSFMT) 2 | ------------------------------------ 3 | 4 | .. module:: randomgen.dsfmt 5 | 6 | .. currentmodule:: randomgen.dsfmt 7 | 8 | 9 | .. autoclass:: DSFMT 10 | 11 | Seeding and State 12 | ================= 13 | 14 | .. autosummary:: 15 | :toctree: generated/ 16 | 17 | ~DSFMT.seed 18 | ~DSFMT.state 19 | 20 | Parallel generation 21 | =================== 22 | .. autosummary:: 23 | :toctree: generated/ 24 | 25 | ~DSFMT.jumped 26 | ~DSFMT.jump 27 | 28 | Extending 29 | ========= 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | ~DSFMT.cffi 34 | ~DSFMT.ctypes 35 | 36 | Testing 37 | ======= 38 | .. autosummary:: 39 | :toctree: generated/ 40 | 41 | ~DSFMT.random_raw 42 | 43 | -------------------------------------------------------------------------------- /doc/source/bit_generators/efiix64.rst: -------------------------------------------------------------------------------- 1 | Entropy From Iteration, Indirection, Xor (EFIIX) Generator 2 | ----------------------------------------------------------- 3 | 4 | .. module:: randomgen.efiix64 5 | 6 | .. currentmodule:: randomgen.efiix64 7 | 8 | .. autoclass:: EFIIX64 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~EFIIX64.seed 17 | ~EFIIX64.state 18 | 19 | Extending 20 | ========= 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~EFIIX64.cffi 25 | ~EFIIX64.ctypes 26 | 27 | Testing 28 | ======= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~EFIIX64.random_raw 33 | -------------------------------------------------------------------------------- /doc/source/bit_generators/hc128.rst: -------------------------------------------------------------------------------- 1 | HC-128 Cipher Generator 2 | ----------------------- 3 | 4 | .. module:: randomgen.hc128 5 | 6 | .. currentmodule:: randomgen.hc128 7 | 8 | .. autoclass:: HC128 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~HC128.seed 17 | ~HC128.state 18 | 19 | Extending 20 | ========= 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~HC128.cffi 25 | ~HC128.ctypes 26 | 27 | Testing 28 | ======= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~HC128.random_raw 33 | -------------------------------------------------------------------------------- /doc/source/bit_generators/index.rst: -------------------------------------------------------------------------------- 1 | Bit Generators 2 | -------------- 3 | 4 | The random values produced by :class:`numpy.random.Generator` 5 | (and also ``Generator``) 6 | are produced by a bit generator. These bit generators do not directly provide 7 | random numbers and only contain methods used for seeding, getting or 8 | setting the state, jumping or advancing the state, and for accessing 9 | low-level wrappers for consumption by code that can efficiently 10 | access the functions provided, e.g., `numba `_. 11 | 12 | Stable RNGs 13 | =========== 14 | These RNGs will be included in future releases. 15 | 16 | 17 | .. toctree:: 18 | :maxdepth: 1 19 | 20 | AES Counter 21 | ChaCha 22 | DSFMT 23 | EFIIX64 24 | HC128 25 | JSF 26 | LXM 27 | MT19937 28 | MT64 29 | PCG32 30 | PCG64 31 | PCG64 2.0 (64-bit multiplier, DXSM mixing) 32 | 128-bit LCG with output mixing 33 | Philox 34 | RDRAND 35 | Romu 36 | SFC64 37 | SFMT 38 | SPECK128 39 | Squares 40 | ThreeFry 41 | Tyche 42 | XoroShiro128+/++ 43 | Xoshiro256** 44 | Xoshiro512** 45 | 46 | Experimental RNGs 47 | ================= 48 | 49 | These RNGs are currently included for testing but are may not be 50 | permanent. 51 | 52 | .. toctree:: 53 | :maxdepth: 1 54 | 55 | Xorshift1024*φ 56 | 57 | User-defined Bit Generators 58 | =========================== 59 | 60 | .. toctree:: 61 | :maxdepth: 1 62 | 63 | userbitgenerator 64 | -------------------------------------------------------------------------------- /doc/source/bit_generators/jsf.rst: -------------------------------------------------------------------------------- 1 | Jenkins Small Fast Generator 2 | ---------------------------- 3 | 4 | .. module:: randomgen.jsf 5 | 6 | .. currentmodule:: randomgen.jsf 7 | 8 | .. autoclass:: JSF 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~JSF.seed 17 | ~JSF.state 18 | 19 | Extending 20 | ========= 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~JSF.cffi 25 | ~JSF.ctypes 26 | 27 | Testing 28 | ======= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~JSF.random_raw 33 | -------------------------------------------------------------------------------- /doc/source/bit_generators/lcg128mix.rst: -------------------------------------------------------------------------------- 1 | 128-bit Linear Congruential Generator (LCG) with Output Mixing 2 | -------------------------------------------------------------- 3 | 4 | .. currentmodule:: randomgen.pcg64 5 | 6 | .. autoclass:: LCG128Mix 7 | 8 | Seeding and State 9 | ================= 10 | 11 | .. autosummary:: 12 | :toctree: generated/ 13 | 14 | ~LCG128Mix.seed 15 | ~LCG128Mix.state 16 | 17 | Parallel generation 18 | =================== 19 | .. autosummary:: 20 | :toctree: generated/ 21 | 22 | ~LCG128Mix.advance 23 | ~LCG128Mix.jumped 24 | 25 | Extending 26 | ========= 27 | .. autosummary:: 28 | :toctree: generated/ 29 | 30 | ~LCG128Mix.cffi 31 | ~LCG128Mix.ctypes 32 | 33 | Testing 34 | ======= 35 | .. autosummary:: 36 | :toctree: generated/ 37 | 38 | ~LCG128Mix.random_raw 39 | -------------------------------------------------------------------------------- /doc/source/bit_generators/lxm.rst: -------------------------------------------------------------------------------- 1 | LXM Generator 2 | ------------- 3 | 4 | .. module:: randomgen.lxm 5 | 6 | .. currentmodule:: randomgen.lxm 7 | 8 | .. autoclass:: LXM 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~LXM.seed 17 | ~LXM.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~LXM.jump 25 | ~LXM.jumped 26 | 27 | Extending 28 | ========= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~LXM.cffi 33 | ~LXM.ctypes 34 | 35 | Testing 36 | ======= 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | ~LXM.random_raw 41 | -------------------------------------------------------------------------------- /doc/source/bit_generators/mt19937.rst: -------------------------------------------------------------------------------- 1 | Mersenne Twister (MT19937) 2 | -------------------------- 3 | 4 | .. module:: randomgen.mt19937 5 | 6 | .. currentmodule:: randomgen.mt19937 7 | 8 | .. autoclass:: MT19937 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~MT19937.seed 17 | ~MT19937.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~MT19937.jump 25 | ~MT19937.jumped 26 | 27 | Extending 28 | ========= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~MT19937.cffi 33 | ~MT19937.ctypes 34 | 35 | Testing 36 | ======= 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | ~MT19937.random_raw 41 | -------------------------------------------------------------------------------- /doc/source/bit_generators/mt64.rst: -------------------------------------------------------------------------------- 1 | 64-bit Mersenne Twister 2 | ----------------------- 3 | 4 | .. module:: randomgen.mt64 5 | 6 | .. currentmodule:: randomgen.mt64 7 | 8 | 9 | .. autoclass:: MT64 10 | 11 | Seeding and State 12 | ================= 13 | 14 | .. autosummary:: 15 | :toctree: generated/ 16 | 17 | ~MT64.seed 18 | ~MT64.state 19 | 20 | Extending 21 | ========= 22 | .. autosummary:: 23 | :toctree: generated/ 24 | 25 | ~MT64.cffi 26 | ~MT64.ctypes 27 | 28 | Testing 29 | ======= 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | ~MT64.random_raw 34 | -------------------------------------------------------------------------------- /doc/source/bit_generators/pcg32.rst: -------------------------------------------------------------------------------- 1 | Permuted Congruential Generator (32-bit, PCG32) 2 | ----------------------------------------------- 3 | 4 | .. module:: randomgen.pcg32 5 | 6 | .. currentmodule:: randomgen.pcg32 7 | 8 | .. autoclass:: PCG32 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~PCG32.seed 17 | ~PCG32.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~PCG32.advance 25 | ~PCG32.jump 26 | ~PCG32.jumped 27 | 28 | Extending 29 | ========= 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | ~PCG32.cffi 34 | ~PCG32.ctypes 35 | 36 | Testing 37 | ======= 38 | .. autosummary:: 39 | :toctree: generated/ 40 | 41 | ~PCG32.random_raw 42 | -------------------------------------------------------------------------------- /doc/source/bit_generators/pcg64.rst: -------------------------------------------------------------------------------- 1 | Permuted Congruential Generator (64-bit, PCG64) 2 | ----------------------------------------------- 3 | 4 | .. module:: randomgen.pcg64 5 | 6 | .. currentmodule:: randomgen.pcg64 7 | 8 | .. autoclass:: PCG64 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~PCG64.seed 17 | ~PCG64.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~PCG64.advance 25 | ~PCG64.jump 26 | ~PCG64.jumped 27 | 28 | Extending 29 | ========= 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | ~PCG64.cffi 34 | ~PCG64.ctypes 35 | 36 | Testing 37 | ======= 38 | .. autosummary:: 39 | :toctree: generated/ 40 | 41 | ~PCG64.random_raw 42 | -------------------------------------------------------------------------------- /doc/source/bit_generators/pcg64dxsm.rst: -------------------------------------------------------------------------------- 1 | Permuted Congruential Generator 2.0 (64-bit Multiplier, DXSM Output) 2 | -------------------------------------------------------------------- 3 | 4 | .. currentmodule:: randomgen.pcg64 5 | 6 | .. autoclass:: PCG64DXSM 7 | 8 | Seeding and State 9 | ================= 10 | 11 | .. autosummary:: 12 | :toctree: generated/ 13 | 14 | ~PCG64DXSM.seed 15 | ~PCG64DXSM.state 16 | 17 | Parallel generation 18 | =================== 19 | .. autosummary:: 20 | :toctree: generated/ 21 | 22 | ~PCG64DXSM.advance 23 | ~PCG64DXSM.jump 24 | ~PCG64DXSM.jumped 25 | 26 | Extending 27 | ========= 28 | .. autosummary:: 29 | :toctree: generated/ 30 | 31 | ~PCG64DXSM.cffi 32 | ~PCG64DXSM.ctypes 33 | 34 | Testing 35 | ======= 36 | .. autosummary:: 37 | :toctree: generated/ 38 | 39 | ~PCG64DXSM.random_raw 40 | -------------------------------------------------------------------------------- /doc/source/bit_generators/philox.rst: -------------------------------------------------------------------------------- 1 | Philox Counter-based RNG 2 | ------------------------ 3 | 4 | .. module:: randomgen.philox 5 | 6 | .. currentmodule:: randomgen.philox 7 | 8 | .. autoclass:: Philox 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~Philox.seed 17 | ~Philox.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~Philox.advance 25 | ~Philox.jump 26 | ~Philox.jumped 27 | 28 | Extending 29 | ========= 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | ~Philox.cffi 34 | ~Philox.ctypes 35 | 36 | Testing 37 | ======= 38 | .. autosummary:: 39 | :toctree: generated/ 40 | 41 | ~Philox.random_raw 42 | -------------------------------------------------------------------------------- /doc/source/bit_generators/rdrand.rst: -------------------------------------------------------------------------------- 1 | Hardware-based Random Number Generator (RDRAND) 2 | ----------------------------------------------- 3 | 4 | .. module:: randomgen.rdrand 5 | 6 | .. currentmodule:: randomgen.rdrand 7 | 8 | .. autoclass:: RDRAND 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~RDRAND.seed 17 | ~RDRAND.state 18 | ~RDRAND.success 19 | 20 | Parallel generation 21 | =================== 22 | .. autosummary:: 23 | :toctree: generated/ 24 | 25 | ~RDRAND.jumped 26 | 27 | Extending 28 | ========= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~RDRAND.cffi 33 | ~RDRAND.ctypes 34 | 35 | Testing 36 | ======= 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | ~RDRAND.random_raw 41 | 42 | Custom Lock 43 | =========== 44 | 45 | .. autoclass:: RaisingLock 46 | -------------------------------------------------------------------------------- /doc/source/bit_generators/romu.rst: -------------------------------------------------------------------------------- 1 | Rotate-Multiply (Romu) Generators 2 | --------------------------------- 3 | 4 | .. module:: randomgen.romu 5 | 6 | .. currentmodule:: randomgen.romu 7 | 8 | .. autoclass:: Romu 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~Romu.seed 17 | ~Romu.state 18 | 19 | Extending 20 | ========= 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~Romu.cffi 25 | ~Romu.ctypes 26 | 27 | Testing 28 | ======= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~Romu.random_raw 33 | -------------------------------------------------------------------------------- /doc/source/bit_generators/sfc.rst: -------------------------------------------------------------------------------- 1 | SFC64 Generator 2 | --------------- 3 | 4 | .. module:: randomgen.sfc 5 | 6 | .. currentmodule:: randomgen.sfc 7 | 8 | .. autoclass:: SFC64 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~SFC64.seed 17 | ~SFC64.state 18 | 19 | Extending 20 | ========= 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~SFC64.cffi 25 | ~SFC64.ctypes 26 | 27 | Testing 28 | ======= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~SFC64.random_raw 33 | 34 | 35 | Parallelization 36 | =============== 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | ~SFC64.weyl_increments 41 | -------------------------------------------------------------------------------- /doc/source/bit_generators/sfmt.rst: -------------------------------------------------------------------------------- 1 | SIMD-oriented Fast Mersenne Twister (SFMT) 2 | ------------------------------------------ 3 | 4 | .. module:: randomgen.sfmt 5 | 6 | .. currentmodule:: randomgen.sfmt 7 | 8 | 9 | .. autoclass:: SFMT 10 | 11 | Seeding and State 12 | ================= 13 | 14 | .. autosummary:: 15 | :toctree: generated/ 16 | 17 | ~SFMT.seed 18 | ~SFMT.state 19 | 20 | Parallel generation 21 | =================== 22 | .. autosummary:: 23 | :toctree: generated/ 24 | 25 | ~SFMT.jumped 26 | ~SFMT.jump 27 | 28 | Extending 29 | ========= 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | ~SFMT.cffi 34 | ~SFMT.ctypes 35 | 36 | Testing 37 | ======= 38 | .. autosummary:: 39 | :toctree: generated/ 40 | 41 | ~SFMT.random_raw 42 | -------------------------------------------------------------------------------- /doc/source/bit_generators/speck128.rst: -------------------------------------------------------------------------------- 1 | SPECK Counter-based RNG 2 | ----------------------- 3 | 4 | .. module:: randomgen.speck128 5 | 6 | .. currentmodule:: randomgen.speck128 7 | 8 | .. autoclass:: SPECK128 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~SPECK128.seed 17 | ~SPECK128.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~SPECK128.advance 25 | ~SPECK128.jump 26 | ~SPECK128.jumped 27 | 28 | Extending 29 | ========= 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | ~SPECK128.cffi 34 | ~SPECK128.ctypes 35 | 36 | Testing 37 | ======= 38 | .. autosummary:: 39 | :toctree: generated/ 40 | 41 | ~SPECK128.random_raw 42 | -------------------------------------------------------------------------------- /doc/source/bit_generators/squares.rst: -------------------------------------------------------------------------------- 1 | Middle Square with Weyl increment (64-bit, Squares) 2 | --------------------------------------------------- 3 | 4 | .. module:: randomgen.squares 5 | 6 | .. currentmodule:: randomgen.squares 7 | 8 | .. autoclass:: Squares 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~Squares.seed 17 | ~Squares.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~Squares.advance 25 | ~Squares.jumped 26 | 27 | Extending 28 | ========= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~Squares.cffi 33 | ~Squares.ctypes 34 | 35 | Testing 36 | ======= 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | ~Squares.random_raw 41 | 42 | Key Generation 43 | ============== 44 | 45 | A convenience function for pre-generating keys that can be 46 | used with the ``key`` argument of Squares is available. This 47 | function transforms the entropy in a :class:`~numpy.random.SeedSequence` 48 | into a 64-bit unsigned integer key that can be used with Squares. 49 | 50 | .. autosummary:: 51 | :toctree: generated/ 52 | 53 | generate_keys 54 | 55 | -------------------------------------------------------------------------------- /doc/source/bit_generators/threefry.rst: -------------------------------------------------------------------------------- 1 | ThreeFry Counter-based RNG 2 | -------------------------- 3 | 4 | .. module:: randomgen.threefry 5 | 6 | .. currentmodule:: randomgen.threefry 7 | 8 | .. autoclass:: ThreeFry 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~ThreeFry.seed 17 | ~ThreeFry.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~ThreeFry.advance 25 | ~ThreeFry.jump 26 | ~ThreeFry.jumped 27 | 28 | Extending 29 | ========= 30 | .. autosummary:: 31 | :toctree: generated/ 32 | 33 | ~ThreeFry.cffi 34 | ~ThreeFry.ctypes 35 | 36 | Testing 37 | ======= 38 | .. autosummary:: 39 | :toctree: generated/ 40 | 41 | ~ThreeFry.random_raw 42 | -------------------------------------------------------------------------------- /doc/source/bit_generators/tyche.rst: -------------------------------------------------------------------------------- 1 | Tyche PRNG 2 | ---------- 3 | 4 | .. module:: randomgen.tyche 5 | 6 | .. currentmodule:: randomgen.tyche 7 | 8 | .. autoclass:: Tyche 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~Tyche.seed 17 | ~Tyche.state 18 | 19 | Extending 20 | ========= 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~Tyche.cffi 25 | ~Tyche.ctypes 26 | 27 | Testing 28 | ======= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~Tyche.random_raw 33 | -------------------------------------------------------------------------------- /doc/source/bit_generators/userbitgenerator.rst: -------------------------------------------------------------------------------- 1 | User-defined Bit Generators 2 | --------------------------- 3 | Most bit generators use Cython to wrap an implementation in C. While this 4 | method leads to best case performance, it is necessarily involved. 5 | :class:`~randomgen.wrapper.UserBitGenerator` allows bit generators to be 6 | written in Python (slow) or numba (fast) or for existing PRNGs to be 7 | wrapped. The bit generator can then be used with a 8 | :class:`~numpy.random.Generator`. See `the demonstration notebook`_ for 9 | examples. 10 | 11 | .. module:: randomgen.wrapper 12 | 13 | .. currentmodule:: randomgen.wrapper 14 | 15 | .. autoclass:: UserBitGenerator 16 | 17 | From Low-level Objects 18 | ====================== 19 | 20 | .. autosummary:: 21 | :toctree: generated/ 22 | 23 | ~UserBitGenerator.from_cfunc 24 | ~UserBitGenerator.from_ctypes 25 | 26 | State 27 | ===== 28 | 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~UserBitGenerator.state 33 | 34 | Extending 35 | ========= 36 | .. autosummary:: 37 | :toctree: generated/ 38 | 39 | ~UserBitGenerator.cffi 40 | ~UserBitGenerator.ctypes 41 | 42 | Testing 43 | ======= 44 | .. autosummary:: 45 | :toctree: generated/ 46 | 47 | ~UserBitGenerator.random_raw 48 | 49 | .. _the demonstration notebook: ../custom-bit-generators.ipynb 50 | -------------------------------------------------------------------------------- /doc/source/bit_generators/xoroshiro128.rst: -------------------------------------------------------------------------------- 1 | Xoroshiro128+ 2 | ------------- 3 | 4 | .. module:: randomgen.xoroshiro128 5 | 6 | .. currentmodule:: randomgen.xoroshiro128 7 | 8 | .. autoclass:: Xoroshiro128 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~Xoroshiro128.seed 17 | ~Xoroshiro128.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~Xoroshiro128.jump 25 | ~Xoroshiro128.jumped 26 | 27 | Extending 28 | ========= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~Xoroshiro128.cffi 33 | ~Xoroshiro128.ctypes 34 | 35 | Testing 36 | ======= 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | ~Xoroshiro128.random_raw 41 | -------------------------------------------------------------------------------- /doc/source/bit_generators/xorshift1024.rst: -------------------------------------------------------------------------------- 1 | Xorshift1024*φ 2 | -------------- 3 | 4 | .. module:: randomgen.xorshift1024 5 | 6 | .. currentmodule:: randomgen.xorshift1024 7 | 8 | .. autoclass:: Xorshift1024 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~Xorshift1024.seed 17 | ~Xorshift1024.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~Xorshift1024.jump 25 | ~Xorshift1024.jumped 26 | 27 | Extending 28 | ========= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~Xorshift1024.cffi 33 | ~Xorshift1024.ctypes 34 | 35 | Testing 36 | ======= 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | ~Xorshift1024.random_raw 41 | -------------------------------------------------------------------------------- /doc/source/bit_generators/xoshiro256.rst: -------------------------------------------------------------------------------- 1 | Xoshiro256** 2 | ------------ 3 | 4 | .. module:: randomgen.xoshiro256 5 | 6 | .. currentmodule:: randomgen.xoshiro256 7 | 8 | .. autoclass:: Xoshiro256 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~Xoshiro256.seed 17 | ~Xoshiro256.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~Xoshiro256.jump 25 | ~Xoshiro256.jumped 26 | 27 | Extending 28 | ========= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~Xoshiro256.cffi 33 | ~Xoshiro256.ctypes 34 | 35 | Testing 36 | ======= 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | ~Xoshiro256.random_raw 41 | -------------------------------------------------------------------------------- /doc/source/bit_generators/xoshiro512.rst: -------------------------------------------------------------------------------- 1 | Xoshiro512** 2 | ------------ 3 | 4 | .. module:: randomgen.xoshiro512 5 | 6 | .. currentmodule:: randomgen.xoshiro512 7 | 8 | .. autoclass:: Xoshiro512 9 | 10 | Seeding and State 11 | ================= 12 | 13 | .. autosummary:: 14 | :toctree: generated/ 15 | 16 | ~Xoshiro512.seed 17 | ~Xoshiro512.state 18 | 19 | Parallel generation 20 | =================== 21 | .. autosummary:: 22 | :toctree: generated/ 23 | 24 | ~Xoshiro512.jump 25 | ~Xoshiro512.jumped 26 | 27 | Extending 28 | ========= 29 | .. autosummary:: 30 | :toctree: generated/ 31 | 32 | ~Xoshiro512.cffi 33 | ~Xoshiro512.ctypes 34 | 35 | Testing 36 | ======= 37 | .. autosummary:: 38 | :toctree: generated/ 39 | 40 | ~Xoshiro512.random_raw 41 | -------------------------------------------------------------------------------- /doc/source/entropy.rst: -------------------------------------------------------------------------------- 1 | System Entropy 2 | ============== 3 | 4 | .. module:: randomgen.entropy 5 | 6 | .. autofunction:: random_entropy 7 | -------------------------------------------------------------------------------- /doc/source/extended-generator.rst: -------------------------------------------------------------------------------- 1 | Extended Generator 2 | ------------------ 3 | The :class:`~randomgen.generator.ExtendedGenerator` provides access to 4 | a small number of distributions that are not present in NumPy. 5 | The default bit generator used by 6 | :class:`~randomgen.generator.ExtendedGenerator` is 7 | :class:`~randomgen.pcg64.PCG64`. The bit generator can be 8 | changed by passing an instantized bit generator to 9 | :class:`~randomgen.generator.ExtendedGenerator`. It is also possible 10 | to share a bit generator with an instance of NumPy's :class:`numpy.random.Generator`. 11 | 12 | .. currentmodule:: randomgen.generator 13 | 14 | .. autoclass:: 15 | ExtendedGenerator 16 | 17 | Seed and State Manipulation 18 | =========================== 19 | .. autosummary:: 20 | :toctree: generated/ 21 | 22 | ~ExtendedGenerator.state 23 | ~ExtendedGenerator.bit_generator 24 | 25 | Distributions 26 | ============= 27 | .. autosummary:: 28 | :toctree: generated/ 29 | 30 | ~ExtendedGenerator.uintegers 31 | ~ExtendedGenerator.random 32 | ~ExtendedGenerator.complex_normal 33 | ~ExtendedGenerator.multivariate_normal 34 | ~ExtendedGenerator.multivariate_complex_normal 35 | ~ExtendedGenerator.standard_wishart 36 | ~ExtendedGenerator.wishart 37 | -------------------------------------------------------------------------------- /doc/source/future.rst: -------------------------------------------------------------------------------- 1 | Future Plans 2 | ------------ 3 | 4 | A substantial portion of randomgen has been merged into NumPy. Revamping NumPy's random 5 | number generation was always the goal of this project (and its predecessor 6 | `NextGen NumPy RandomState `_), 7 | and so it has succeeded. 8 | 9 | The future plans for randomgen are: 10 | 11 | * ``Generator`` and ``RandomState`` have been **removed** in 1.23. 12 | * Put the novel methods of ``Generator`` in a 13 | :class:`~randomgen.generator.ExtendedGenerator`. :class:`~randomgen.generator.ExtendedGenerator` 14 | will be maintained, although it is possible that some of the methods may 15 | migrate to NumPy. 16 | * Add useful distributions that are not supported in NumPy. Pull requests adding useful 17 | generators are welcome. 18 | * Add any novel and interesting bit generators, and extend that capabilities of existing ones. 19 | 20 | -------------------------------------------------------------------------------- /doc/source/generator.rst: -------------------------------------------------------------------------------- 1 | Random Generator 2 | ---------------- 3 | 4 | .. container:: admonition danger 5 | 6 | .. raw:: html 7 | 8 |

Removed

9 | 10 | .. danger:: 11 | 12 | ``Generator`` has been completely **removed** in randomgen 2.0.0. 13 | You should be using :class:`numpy.random.Generator`. 14 | 15 | -------------------------------------------------------------------------------- /doc/source/images/casino.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 34 | 38 | 39 | -------------------------------------------------------------------------------- /doc/source/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bashtage/randomgen/34bc41ac41b94a0df9806fdd4ed242531b520e3a/doc/source/images/favicon.ico -------------------------------------------------------------------------------- /doc/source/legacy.rst: -------------------------------------------------------------------------------- 1 | Legacy Random Generation 2 | ------------------------ 3 | 4 | 5 | .. container:: admonition danger 6 | 7 | .. raw:: html 8 | 9 |

Removed

10 | 11 | .. danger:: 12 | 13 | ``RandomState`` has been completely **removed** in randomgen 2.0.0. 14 | You should be using :class:`numpy.random.Generator`, or if you must 15 | have full stability (e.g., for writing tests) or backward compatibility 16 | with NumPy before 1.17, :class:`numpy.random.RandomState`. 17 | -------------------------------------------------------------------------------- /doc/source/names_wordlist.txt: -------------------------------------------------------------------------------- 1 | Abbt 2 | Abramowitz 3 | Anstalts 4 | Badi 5 | Baltagi 6 | Basmann 7 | Baum 8 | Beaulieu 9 | Biostatistics 10 | Birkhauser 11 | Blackman 12 | Bogden 13 | Bryzgalova 14 | Buzas 15 | Chhikara 16 | Cochrane 17 | Corbet 18 | Culver 19 | Dalgaard 20 | Daly 21 | Dataplot 22 | De 23 | Doty 24 | Driscoll 25 | Dror 26 | Duda 27 | Durbin 28 | Ecuyer 29 | Edler 30 | Elo 31 | Fama 32 | Filliben 33 | Forlag 34 | François 35 | Frechet 36 | Gelbach 37 | Generalstabens 38 | Georgios 39 | Glantz 40 | Gosset 41 | Grunfeld 42 | Halliwell 43 | Hamann 44 | Handlingar 45 | Haramoto 46 | Hausman 47 | Heckert 48 | Henningsen 49 | Hiroshi 50 | Hongjun 51 | Ingeniorsvetenskapsakademiens 52 | Jagannathan 53 | Kleiber 54 | Kotz 55 | Kraay 56 | L'Ecuyer 57 | Lausanne 58 | Lemire 59 | Lentner 60 | Limpert 61 | Litografiska 62 | Lomax 63 | Lunn 64 | MacBeth 65 | Makoto 66 | Marsaglia 67 | Matsumoto 68 | Mises 69 | Moivre 70 | Moraes 71 | Munnell 72 | Mutsuo 73 | Neill 74 | Newey 75 | Nishimura 76 | Numba 77 | Numpy 78 | Ostrowski 79 | Panneton 80 | Papoulis 81 | Peebles 82 | Peyton 83 | Pravin 84 | Quigley 85 | Raj 86 | Rammler 87 | Reiss 88 | Saito 89 | Sargan 90 | Schaffer 91 | Sebastiano 92 | Shors 93 | Skoulakis 94 | Springer 95 | Stahel 96 | Stata 97 | Stata 98 | Stegun 99 | Stillman 100 | Svetlana 101 | Takuji 102 | Treatman 103 | Trivedi 104 | Tsang 105 | Tweedie 106 | Vella 107 | Verbeek 108 | Verlag 109 | Vigna 110 | Vilfredo 111 | Waloddi 112 | Weibull 113 | Weisstein 114 | Wooldridge 115 | Zhenyu 116 | ecuyer 117 | Overton 118 | Horner 119 | Feiveson 120 | Jour 121 | Uhlig 122 | Dıaz 123 | Garcıa 124 | Jáimez 125 | Mardia 126 | -------------------------------------------------------------------------------- /doc/source/references.rst: -------------------------------------------------------------------------------- 1 | References 2 | ---------- 3 | 4 | .. [Lemire] Daniel Lemire., "Fast Random Integer Generation in an Interval", 5 | CoRR, Aug. 13, 2018, https://arxiv.org/abs/1805.10941. 6 | -------------------------------------------------------------------------------- /doc/source/savefig/.empty-folder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bashtage/randomgen/34bc41ac41b94a0df9806fdd4ed242531b520e3a/doc/source/savefig/.empty-folder -------------------------------------------------------------------------------- /doc/source/seed_sequence.rst: -------------------------------------------------------------------------------- 1 | Seed Sequences 2 | -------------- 3 | 4 | .. note:: 5 | 6 | randomgen imports :class:`~numpy.random.SeedSequence` from NumPy. As of version 2.0.0, randomgen does not provide 7 | a vendored copy of ``SeedSequence``. 8 | 9 | .. deprecated:: 2.0.0 10 | 11 | ``SeedSequence`` is now available in NumPy. Use :class:`~numpy.random.SeedSequence` 12 | instead. Importing ``SeedSequence`` from randomgen will be removed in a future version. 13 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "packaging>=21.0", 4 | "setuptools", 5 | "wheel", 6 | "Cython>=3.0.10,<4", 7 | "numpy>=2.0.0rc1,<3", 8 | "setuptools_scm[toml]>=8.0.0,<9.0.0", 9 | ] 10 | build-backend = "setuptools.build_meta" 11 | 12 | [tool.setuptools_scm] 13 | write_to = "randomgen/_version.py" 14 | -------------------------------------------------------------------------------- /randomgen/_deprecated_value.py: -------------------------------------------------------------------------------- 1 | class _DeprecatedValueType: 2 | """Special keyword value for deprecated arguments.. 3 | 4 | The instance of this class may be used as the default value assigned to a 5 | keyword if the parameter is deprecated. 6 | """ 7 | 8 | __instance = None 9 | 10 | def __new__(cls): 11 | # ensure that only one instance exists 12 | if not cls.__instance: 13 | cls.__instance = super().__new__(cls) 14 | return cls.__instance 15 | 16 | def __repr__(self): 17 | return "" 18 | 19 | 20 | _DeprecatedValue = _DeprecatedValueType() 21 | 22 | __all__ = ["_DeprecatedValue"] 23 | -------------------------------------------------------------------------------- /randomgen/_register.py: -------------------------------------------------------------------------------- 1 | from numpy.random._pickle import BitGenerators 2 | 3 | from randomgen.aes import AESCounter 4 | from randomgen.chacha import ChaCha 5 | from randomgen.dsfmt import DSFMT 6 | from randomgen.efiix64 import EFIIX64 7 | from randomgen.hc128 import HC128 8 | from randomgen.jsf import JSF 9 | from randomgen.lxm import LXM 10 | from randomgen.mt64 import MT64 11 | from randomgen.mt19937 import MT19937 12 | from randomgen.pcg32 import PCG32 13 | from randomgen.pcg64 import PCG64, PCG64DXSM, LCG128Mix 14 | from randomgen.philox import Philox 15 | from randomgen.rdrand import RDRAND 16 | from randomgen.romu import Romu 17 | from randomgen.sfc import SFC64 18 | from randomgen.sfmt import SFMT 19 | from randomgen.speck128 import SPECK128 20 | from randomgen.squares import Squares 21 | from randomgen.threefry import ThreeFry 22 | from randomgen.tyche import Tyche 23 | from randomgen.wrapper import UserBitGenerator 24 | from randomgen.xoroshiro128 import Xoroshiro128 25 | from randomgen.xorshift1024 import Xorshift1024 26 | from randomgen.xoshiro256 import Xoshiro256 27 | from randomgen.xoshiro512 import Xoshiro512 28 | 29 | bit_generators = [ 30 | AESCounter, 31 | ChaCha, 32 | DSFMT, 33 | EFIIX64, 34 | HC128, 35 | JSF, 36 | LXM, 37 | MT19937, 38 | MT64, 39 | PCG32, 40 | PCG64, 41 | PCG64DXSM, 42 | LCG128Mix, 43 | Philox, 44 | RDRAND, 45 | Romu, 46 | SFC64, 47 | SFMT, 48 | SPECK128, 49 | Squares, 50 | ThreeFry, 51 | Tyche, 52 | UserBitGenerator, 53 | Xoroshiro128, 54 | Xorshift1024, 55 | Xoshiro256, 56 | Xoshiro512, 57 | ] 58 | 59 | for bitgen in bit_generators: 60 | key = f"{bitgen.__name__}" 61 | if key not in BitGenerators: 62 | BitGenerators[key] = bitgen 63 | full_key = f"{bitgen.__module__}.{bitgen.__name__}" 64 | BitGenerators[full_key] = bitgen 65 | 66 | __all__ = ["BitGenerators"] 67 | -------------------------------------------------------------------------------- /randomgen/_seed_sequence.pxd: -------------------------------------------------------------------------------- 1 | 2 | cimport numpy as np 3 | from libc.stdint cimport uint32_t 4 | 5 | 6 | cdef class SeedSequence(object): 7 | cdef readonly object entropy 8 | cdef readonly tuple spawn_key 9 | cdef readonly Py_ssize_t pool_size 10 | cdef readonly object pool 11 | cdef readonly uint32_t n_children_spawned 12 | 13 | cdef mix_entropy(self, np.ndarray[np.npy_uint32, ndim=1] mixer, 14 | np.ndarray[np.npy_uint32, ndim=1] entropy_array) 15 | cdef get_assembled_entropy(self) 16 | 17 | cdef class SeedlessSequence(object): 18 | pass 19 | -------------------------------------------------------------------------------- /randomgen/_seed_sequence.pyi: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | from collections.abc import Sequence 3 | from typing import Any 4 | 5 | from numpy import unsignedinteger 6 | 7 | DEFAULT_POOL_SIZE: int 8 | 9 | class ISeedSequence(metaclass=ABCMeta): 10 | @abstractmethod 11 | def generate_state( 12 | self, n_words: int, dtype: type[unsignedinteger[Any]] = ... 13 | ) -> Sequence[int]: ... 14 | 15 | class ISpawnableSeedSequence(ISeedSequence, metaclass=ABCMeta): 16 | @abstractmethod 17 | def spawn(self, n_children: int) -> list[SeedSequence]: ... 18 | 19 | class SeedSequence(ISpawnableSeedSequence): 20 | def __init__( 21 | self, 22 | entropy: int | Sequence[int] | None = ..., 23 | *, 24 | spawn_key: Sequence[int] = ..., 25 | pool_size: int = ..., 26 | n_children_spawned: int = ... 27 | ) -> None: ... 28 | @property 29 | def state(self) -> dict[str, int | Sequence[int]]: ... 30 | def generate_state( 31 | self, n_words: int, dtype: type[unsignedinteger[Any]] = ... 32 | ) -> Sequence[int]: ... 33 | def spawn(self, n_children: int) -> list[SeedSequence]: ... 34 | 35 | class SeedlessSeedSequence(ISeedSequence): 36 | def generate_state( 37 | self, n_words: int, dtype: type[unsignedinteger[Any]] = ... 38 | ) -> Sequence[int]: ... 39 | def spawn(self, n_children: int) -> list[SeedlessSeedSequence]: ... 40 | -------------------------------------------------------------------------------- /randomgen/aes.pxd: -------------------------------------------------------------------------------- 1 | 2 | 3 | cimport numpy as np 4 | from libc.stdint cimport uint8_t, uint32_t, uint64_t 5 | 6 | from randomgen.common cimport ( 7 | BitGenerator, 8 | PyArray_calloc_aligned, 9 | PyArray_free_aligned, 10 | fully_qualified_name, 11 | int_to_array, 12 | object_to_int, 13 | uint64_to_double, 14 | wrap_int, 15 | ) 16 | 17 | 18 | cdef extern from "src/aesctr/aesctr.h": 19 | 20 | # int are placeholders only for 21 | struct AESCTR_STATE_T: 22 | int ctr[4] 23 | int seed[10 + 1] 24 | uint8_t state[16 * 4] 25 | size_t offset 26 | int has_uint32 27 | uint32_t uinteger 28 | 29 | ctypedef AESCTR_STATE_T aesctr_state_t 30 | 31 | uint64_t aes_next64(aesctr_state_t *aesctr) noexcept nogil 32 | uint32_t aes_next32(aesctr_state_t *aesctr) noexcept nogil 33 | double aes_next_double(aesctr_state_t *aesctr) noexcept nogil 34 | 35 | int RANDOMGEN_USE_AESNI 36 | void aesctr_use_aesni(int val) 37 | void aesctr_seed(aesctr_state_t *aesctr, uint64_t *seed) 38 | void aesctr_set_seed_counter( 39 | aesctr_state_t *aesctr, uint64_t *seed, uint64_t *counter 40 | ) 41 | void aesctr_get_seed_counter( 42 | aesctr_state_t *aesctr, uint64_t *seed, uint64_t *counter 43 | ) 44 | int aes_capable() 45 | void aesctr_advance(aesctr_state_t *aesctr, uint64_t *step) 46 | void aesctr_set_counter(aesctr_state_t *aesctr, uint64_t *counter) 47 | 48 | 49 | cdef class AESCounter(BitGenerator): 50 | 51 | cdef aesctr_state_t *rng_state 52 | cdef _reset_state_variables(self) 53 | cdef jump_inplace(self, object iter) 54 | -------------------------------------------------------------------------------- /randomgen/aes.pyi: -------------------------------------------------------------------------------- 1 | from collections.abc import Sequence 2 | 3 | from numpy import ndarray 4 | 5 | from randomgen.common import BitGenerator 6 | from randomgen.typing import IntegerSequenceSeed, SeedMode 7 | 8 | class AESCounter(BitGenerator): 9 | def __init__( 10 | self, 11 | seed: IntegerSequenceSeed | None = ..., 12 | *, 13 | counter: int | Sequence[int] | None = ..., 14 | key: int | Sequence[int] | None = ..., 15 | mode: SeedMode | None = ... 16 | ) -> None: ... 17 | @property 18 | def use_aesni(self) -> bool: ... 19 | @use_aesni.setter 20 | def use_aesni(self, value: bool) -> None: ... 21 | def seed( 22 | self, 23 | seed: int | Sequence[int] = ..., 24 | counter: int | Sequence[int] | None = ..., 25 | key: int | Sequence[int] | None = ..., 26 | ) -> None: ... 27 | @property 28 | def state(self) -> dict[str, str | dict[str, int | ndarray] | int]: ... 29 | @state.setter 30 | def state(self, value: dict[str, str | dict[str, int | ndarray] | int]) -> None: ... 31 | def jump(self, iter: int = ...) -> AESCounter: ... 32 | def jumped(self, iter: int = ...) -> AESCounter: ... 33 | def advance(self, delta: int) -> AESCounter: ... 34 | -------------------------------------------------------------------------------- /randomgen/api.pxd: -------------------------------------------------------------------------------- 1 | """ 2 | Needed to allow NumPy API 1.7 with Cython < 0.29 3 | Can be removed once minimum Cython is 0.29 4 | """ 5 | 6 | cdef extern from "numpy/arrayobject.h": 7 | enum: 8 | NPY_ARRAY_C_CONTIGUOUS 9 | NPY_ARRAY_F_CONTIGUOUS 10 | NPY_ARRAY_OWNDATA 11 | NPY_ARRAY_FORCECAST 12 | NPY_ARRAY_ENSURECOPY 13 | NPY_ARRAY_ENSUREARRAY 14 | NPY_ARRAY_ELEMENTSTRIDES 15 | NPY_ARRAY_ALIGNED 16 | NPY_ARRAY_NOTSWAPPED 17 | NPY_ARRAY_WRITEABLE 18 | NPY_ARRAY_UPDATEIFCOPY 19 | 20 | NPY_ARRAY_BEHAVED 21 | NPY_ARRAY_BEHAVED_NS 22 | NPY_ARRAY_CARRAY 23 | NPY_ARRAY_CARRAY_RO 24 | NPY_ARRAY_FARRAY 25 | NPY_ARRAY_FARRAY_RO 26 | NPY_ARRAY_DEFAULT 27 | 28 | NPY_ARRAY_IN_ARRAY 29 | NPY_ARRAY_OUT_ARRAY 30 | NPY_ARRAY_INOUT_ARRAY 31 | NPY_ARRAY_IN_FARRAY 32 | NPY_ARRAY_OUT_FARRAY 33 | NPY_ARRAY_INOUT_FARRAY 34 | 35 | NPY_ARRAY_UPDATE_ALL 36 | -------------------------------------------------------------------------------- /randomgen/bounded_integers.pxd.in: -------------------------------------------------------------------------------- 1 | from libc.stdint cimport ( 2 | int8_t, 3 | int16_t, 4 | int32_t, 5 | int64_t, 6 | intptr_t, 7 | uint8_t, 8 | uint16_t, 9 | uint32_t, 10 | uint64_t, 11 | ) 12 | 13 | import numpy as np 14 | 15 | cimport numpy as np 16 | 17 | ctypedef np.npy_bool bool_t 18 | 19 | from randomgen.common cimport bitgen_t 20 | 21 | 22 | cdef inline uint64_t _gen_mask(uint64_t max_val) noexcept nogil: 23 | """Mask generator for use in bounded random numbers""" 24 | # Smallest bit mask >= max 25 | cdef uint64_t mask = max_val 26 | mask |= mask >> 1 27 | mask |= mask >> 2 28 | mask |= mask >> 4 29 | mask |= mask >> 8 30 | mask |= mask >> 16 31 | mask |= mask >> 32 32 | return mask 33 | {{ 34 | py: 35 | inttypes = ("uint64","uint32","uint16","uint8","bool","int64","int32","int16","int8") 36 | }} 37 | {{for inttype in inttypes}} 38 | cdef object _rand_{{inttype}}(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) 39 | {{endfor}} 40 | -------------------------------------------------------------------------------- /randomgen/chacha.pxd: -------------------------------------------------------------------------------- 1 | 2 | 3 | cimport numpy as np 4 | from libc.stdint cimport uint32_t, uint64_t 5 | 6 | from randomgen.common cimport ( 7 | BitGenerator, 8 | PyArray_free_aligned, 9 | PyArray_malloc_aligned, 10 | fully_qualified_name, 11 | int_to_array, 12 | object_to_int, 13 | view_little_endian, 14 | ) 15 | 16 | 17 | cdef extern from "src/chacha/chacha.h": 18 | 19 | int RANDOMGEN_USE_SIMD 20 | 21 | struct CHACHA_STATE_T: 22 | uint32_t block[16] 23 | uint32_t keysetup[8] 24 | uint64_t ctr[2] 25 | int rounds 26 | 27 | ctypedef CHACHA_STATE_T chacha_state_t 28 | 29 | uint32_t chacha_next32(chacha_state_t *state) noexcept nogil 30 | uint64_t chacha_next64(chacha_state_t *state) noexcept nogil 31 | double chacha_next_double(chacha_state_t *state) noexcept nogil 32 | 33 | void chacha_seed( 34 | chacha_state_t *state, 35 | uint64_t *seedval, 36 | uint64_t *stream, 37 | uint64_t *ctr 38 | ) 39 | void chacha_advance(chacha_state_t *state, uint64_t *delta) 40 | int chacha_simd_capable() 41 | void chacha_use_simd(int value) 42 | 43 | cdef class ChaCha(BitGenerator): 44 | 45 | cdef chacha_state_t *rng_state 46 | -------------------------------------------------------------------------------- /randomgen/chacha.pyi: -------------------------------------------------------------------------------- 1 | from collections.abc import Sequence 2 | 3 | from numpy import ndarray 4 | 5 | from randomgen.common import BitGenerator 6 | from randomgen.typing import IntegerSequenceSeed, SeedMode 7 | 8 | class ChaCha(BitGenerator): 9 | def __init__( 10 | self, 11 | seed: IntegerSequenceSeed | None = ..., 12 | *, 13 | counter: int | Sequence[int] | None = ..., 14 | key: int | Sequence[int] | None = ..., 15 | rounds: int = ..., 16 | mode: SeedMode | None = ... 17 | ) -> None: ... 18 | @property 19 | def use_simd(self) -> bool: ... 20 | @use_simd.setter 21 | def use_simd(self, value: bool) -> None: ... 22 | def seed( 23 | self, 24 | seed: IntegerSequenceSeed | None = ..., 25 | counter: int | Sequence[int] | None = ..., 26 | key: int | Sequence[int] | None = ..., 27 | ) -> None: ... 28 | @property 29 | def state(self) -> dict[str, str | dict[str, ndarray | int]]: ... 30 | @state.setter 31 | def state(self, value: dict[str, str | dict[str, ndarray | int]]) -> None: ... 32 | -------------------------------------------------------------------------------- /randomgen/common.pyi: -------------------------------------------------------------------------------- 1 | from typing import Any, NamedTuple 2 | 3 | from numpy import ndarray 4 | 5 | from randomgen.seed_sequence import SeedSequence 6 | from randomgen.typing import IntegerSequenceSeed, SeedMode 7 | 8 | class interface(NamedTuple): 9 | state_address: int 10 | state: int 11 | next_uint64: int 12 | next_uint32: int 13 | next_double: int 14 | bit_generator: int 15 | 16 | class BitGenerator: 17 | seed_seq: SeedSequence 18 | def __init__( 19 | self, 20 | seed: IntegerSequenceSeed = ..., 21 | mode: SeedMode | None = ..., 22 | ) -> None: ... 23 | def random_raw( 24 | self, size: int | None = ..., output: bool = ... 25 | ) -> int | ndarray | None: ... 26 | def _benchmark(self, cnt: int, method: str = ...) -> None: ... 27 | @property 28 | def ctypes(self) -> Any: ... 29 | @property 30 | def cffi(self) -> Any: ... 31 | -------------------------------------------------------------------------------- /randomgen/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | def pytest_configure(config): 5 | # Minimal config to simplify running tests from lm.test() 6 | config.addinivalue_line("markers", "slow: mark a test as slow") 7 | config.addinivalue_line("filterwarnings", "ignore:Generator:FutureWarning") 8 | config.addinivalue_line("filterwarnings", "ignore:RandomState:FutureWarning") 9 | config.addinivalue_line( 10 | "filterwarnings", "ignore:The default value of inc:FutureWarning" 11 | ) 12 | 13 | 14 | def pytest_addoption(parser): 15 | parser.addoption("--skip-slow", action="store_true", help="skip slow tests") 16 | parser.addoption("--only-slow", action="store_true", help="run only slow tests") 17 | 18 | 19 | def pytest_runtest_setup(item): 20 | if "slow" in item.keywords and item.config.getoption("--skip-slow"): 21 | pytest.skip("skipping due to --skip-slow") 22 | 23 | if "slow" not in item.keywords and item.config.getoption("--only-slow"): 24 | pytest.skip("skipping due to --only-slow") 25 | -------------------------------------------------------------------------------- /randomgen/distributions.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | 3 | from libc.stdint cimport ( 4 | int8_t, 5 | int16_t, 6 | int32_t, 7 | int64_t, 8 | intptr_t, 9 | uint8_t, 10 | uint16_t, 11 | uint32_t, 12 | uint64_t, 13 | ) 14 | 15 | import numpy as np 16 | 17 | cimport numpy as np 18 | from numpy.random cimport bitgen_t 19 | 20 | ctypedef uint64_t (*next_uint64_t)(void *st) noexcept nogil 21 | ctypedef uint32_t (*next_uint32_t)(void *st) noexcept nogil 22 | ctypedef double (*next_double_t)(void *st) noexcept nogil 23 | 24 | cdef extern from "src/distributions/rg-distributions.h": 25 | void random_double_fill(bitgen_t * bitgen_state, np.npy_intp cnt, double *out) noexcept nogil 26 | void random_long_double_fill(bitgen_t * bitgen_state, np.npy_intp cnt, long double *out) noexcept nogil 27 | void random_wishart_large_df(bitgen_t *bitgen_state, int64_t df, np.npy_intp dim, np.npy_intp num, double *w, double *n) noexcept nogil 28 | 29 | long double random_long_double(bitgen_t *bitgen_state) noexcept nogil 30 | 31 | float random_float(bitgen_t *bitgen_state) noexcept nogil 32 | 33 | int random_long_double_size() noexcept nogil 34 | -------------------------------------------------------------------------------- /randomgen/dsfmt.pxd: -------------------------------------------------------------------------------- 1 | 2 | cimport numpy as np 3 | from libc.stdint cimport uint32_t, uint64_t 4 | 5 | from randomgen.common cimport ( 6 | BitGenerator, 7 | PyArray_calloc_aligned, 8 | PyArray_free_aligned, 9 | PyArray_malloc_aligned, 10 | check_state_array, 11 | fully_qualified_name, 12 | ) 13 | 14 | DEF DSFMT_MEXP = 19937 15 | DEF DSFMT_N = 191 # ((DSFMT_MEXP - 128) / 104 + 1) 16 | DEF DSFMT_N_PLUS_1 = 192 # DSFMT_N + 1 17 | DEF DSFMT_N64 = DSFMT_N * 2 18 | 19 | cdef extern from "src/dsfmt/dsfmt.h": 20 | 21 | union W128_T: 22 | uint64_t u[2] 23 | uint32_t u32[4] 24 | double d[2] 25 | 26 | ctypedef W128_T w128_t 27 | 28 | struct DSFMT_T: 29 | w128_t status[DSFMT_N_PLUS_1] 30 | int idx 31 | 32 | ctypedef DSFMT_T dsfmt_t 33 | 34 | struct DSFMT_STATE_T: 35 | dsfmt_t *state 36 | double *buffered_uniforms 37 | int buffer_loc 38 | 39 | ctypedef DSFMT_STATE_T dsfmt_state_t 40 | 41 | double dsfmt_next_double(dsfmt_state_t *state) noexcept nogil 42 | uint64_t dsfmt_next64(dsfmt_state_t *state) noexcept nogil 43 | uint32_t dsfmt_next32(dsfmt_state_t *state) noexcept nogil 44 | uint64_t dsfmt_next_raw(dsfmt_state_t *state) noexcept nogil 45 | 46 | void dsfmt_init_gen_rand(dsfmt_t *dsfmt, uint32_t seed) 47 | void dsfmt_init_by_array(dsfmt_t *dsfmt, uint32_t init_key[], int key_length) 48 | void dsfmt_jump(dsfmt_state_t *state) 49 | void dsfmt_jump_n(dsfmt_state_t *state, int count) 50 | 51 | cdef class DSFMT(BitGenerator): 52 | 53 | cdef dsfmt_state_t rng_state 54 | cdef jump_inplace(self, object iter) 55 | cdef _reset_state_variables(self) 56 | -------------------------------------------------------------------------------- /randomgen/dsfmt.pyi: -------------------------------------------------------------------------------- 1 | from collections.abc import Sequence 2 | 3 | import numpy as np 4 | from typing_extensions import TypeAlias 5 | 6 | from randomgen.common import BitGenerator 7 | from randomgen.typing import IntegerSequenceSeed, SeedMode 8 | 9 | DSFMTState: TypeAlias = dict[str, str | int | np.ndarray | dict[str, int | np.ndarray]] 10 | 11 | class DSFMT(BitGenerator): 12 | def __init__( 13 | self, seed: IntegerSequenceSeed | None = ..., *, mode: SeedMode | None = ... 14 | ) -> None: ... 15 | def seed(self, seed: int | Sequence[int] = ...) -> None: ... 16 | def jump(self, iter: int = ...) -> DSFMT: ... 17 | def jumped(self, iter: int = ...) -> DSFMT: ... 18 | @property 19 | def state(self) -> DSFMTState: ... 20 | @state.setter 21 | def state(self, value: DSFMTState) -> None: ... 22 | -------------------------------------------------------------------------------- /randomgen/efiix64.pxd: -------------------------------------------------------------------------------- 1 | 2 | 3 | cimport numpy as np 4 | from libc.stdint cimport uint32_t, uint64_t 5 | 6 | from randomgen.common cimport ( 7 | BitGenerator, 8 | check_state_array, 9 | fully_qualified_name, 10 | uint64_to_double, 11 | ) 12 | 13 | DEF INDIRECTION_SIZE = 16 14 | DEF ITERATION_SIZE = 32 15 | 16 | cdef extern from "src/efiix64/efiix64.h": 17 | 18 | struct EFIIX64_STATE_T: 19 | uint64_t indirection_table[INDIRECTION_SIZE] 20 | uint64_t iteration_table[ITERATION_SIZE] 21 | uint64_t i, a, b, c 22 | int has_uint32 23 | uint32_t uinteger 24 | 25 | ctypedef EFIIX64_STATE_T efiix64_state_t 26 | 27 | uint64_t efiix64_next64(efiix64_state_t *state) noexcept nogil 28 | uint32_t efiix64_next32(efiix64_state_t *state) noexcept nogil 29 | void efiix64_seed(efiix64_state_t *state, uint64_t seed[4]) 30 | 31 | 32 | cdef class EFIIX64(BitGenerator): 33 | 34 | cdef efiix64_state_t rng_state 35 | cdef _reset_state_variables(self) 36 | -------------------------------------------------------------------------------- /randomgen/efiix64.pyi: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed 5 | 6 | class EFIIX64(BitGenerator): 7 | def __init__(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 8 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 9 | @property 10 | def state( 11 | self, 12 | ) -> dict[str, str | int | dict[str, int | np.ndarray]]: ... 13 | @state.setter 14 | def state( 15 | self, value: dict[str, str | int | dict[str, int | np.ndarray]] 16 | ) -> None: ... 17 | -------------------------------------------------------------------------------- /randomgen/entropy.pyi: -------------------------------------------------------------------------------- 1 | from typing import Literal 2 | 3 | import numpy as np 4 | 5 | def seed_by_array(seed: int | np.ndarray, n: int) -> np.ndarray: ... 6 | def random_entropy( 7 | size: int | tuple[int, ...] = ..., 8 | source: Literal["system", "fallback", "auto"] = ..., 9 | ) -> int | np.ndarray: ... 10 | -------------------------------------------------------------------------------- /randomgen/examples/cython/extending_distributions.pyx: -------------------------------------------------------------------------------- 1 | # cython: language_level=3 2 | import numpy as np 3 | 4 | cimport cython 5 | cimport numpy as np 6 | from cpython.pycapsule cimport PyCapsule_GetPointer, PyCapsule_IsValid 7 | 8 | from randomgen.common cimport * 9 | from randomgen.distributions cimport random_gauss_zig 10 | 11 | from randomgen.xoroshiro128 import Xoroshiro128 12 | 13 | 14 | @cython.boundscheck(False) 15 | @cython.wraparound(False) 16 | def normals_zig(Py_ssize_t n): 17 | cdef Py_ssize_t i 18 | cdef bitgen_t *rng 19 | cdef const char *capsule_name = "BitGenerator" 20 | cdef double[::1] random_values 21 | 22 | x = Xoroshiro128() 23 | capsule = x.capsule 24 | if not PyCapsule_IsValid(capsule, capsule_name): 25 | raise ValueError("Invalid pointer to anon_func_state") 26 | rng = PyCapsule_GetPointer(capsule, capsule_name) 27 | random_values = np.empty(n) 28 | for i in range(n): 29 | random_values[i] = random_gauss_zig(rng) 30 | randoms = np.asarray(random_values) 31 | return randoms 32 | 33 | 34 | @cython.boundscheck(False) 35 | @cython.wraparound(False) 36 | def uniforms(Py_ssize_t n): 37 | cdef Py_ssize_t i 38 | cdef bitgen_t *rng 39 | cdef const char *capsule_name = "BitGenerator" 40 | cdef double[::1] random_values 41 | 42 | x = Xoroshiro128() 43 | capsule = x.capsule 44 | # Optional check that the capsule if from a BitGenerator 45 | if not PyCapsule_IsValid(capsule, capsule_name): 46 | raise ValueError("Invalid pointer to anon_func_state") 47 | # Cast the pointer 48 | rng = PyCapsule_GetPointer(capsule, capsule_name) 49 | random_values = np.empty(n) 50 | for i in range(n): 51 | # Call the function 52 | random_values[i] = rng.next_double(rng.state) 53 | randoms = np.asarray(random_values) 54 | return randoms 55 | -------------------------------------------------------------------------------- /randomgen/examples/cython/low_level.pyx: -------------------------------------------------------------------------------- 1 | # cython: language_level=3, boundscheck=False, wraparound=False 2 | from cpython.pycapsule cimport PyCapsule_GetPointer, PyCapsule_IsValid 3 | from libc.stdint cimport uint32_t 4 | 5 | import numpy as np 6 | 7 | cimport cython 8 | cimport numpy as np 9 | 10 | from randomgen.common cimport bitgen_t, uint64_to_double 11 | from randomgen.xoshiro256 cimport Xoshiro256, xoshiro256_next64 12 | 13 | from randomgen.xoshiro256 import Xoshiro256 14 | 15 | np.import_array() 16 | 17 | 18 | def uniform_using_bitgen(Py_ssize_t n): 19 | """ 20 | Example showing how to use the standarzed interface provided by bitgen 21 | """ 22 | 23 | cdef Py_ssize_t i 24 | cdef bitgen_t *rng 25 | cdef const char *capsule_name = "BitGenerator" 26 | cdef double sum = 0.0 27 | 28 | x = Xoshiro256() 29 | capsule = x.capsule 30 | if not PyCapsule_IsValid(capsule, capsule_name): 31 | raise ValueError("Invalid pointer to anon_func_state") 32 | rng = PyCapsule_GetPointer(capsule, capsule_name) 33 | 34 | for i in range(n): 35 | sum += rng.next_double(rng.state) 36 | return sum / n 37 | 38 | 39 | def uniform_using_lowlevel(Py_ssize_t n): 40 | """ 41 | Example showing how to use the low-level interface provided by the pxd file 42 | """ 43 | cdef Py_ssize_t i 44 | cdef double[::1] random_values 45 | cdef double sum = 0.0 46 | 47 | x = Xoshiro256() 48 | 49 | for i in range(n): 50 | sum += uint64_to_double(xoshiro256_next64(&(x).rng_state)) 51 | return sum / n 52 | -------------------------------------------------------------------------------- /randomgen/examples/cython/setup.py: -------------------------------------------------------------------------------- 1 | # python setup.py build_ext -i 2 | from setuptools import setup 3 | from setuptools.extension import Extension 4 | 5 | from os.path import join 6 | 7 | from Cython.Build import cythonize 8 | import numpy as np 9 | 10 | extending = Extension( 11 | "extending", sources=["extending.pyx"], include_dirs=[np.get_include()] 12 | ) 13 | distributions = Extension( 14 | "extending_distributions", 15 | sources=[ 16 | "extending_distributions.pyx", 17 | join( 18 | "..", 19 | "..", 20 | "..", 21 | "randomgen", 22 | "src", 23 | "distributions", 24 | "distributions.orig.c", 25 | ), 26 | ], 27 | include_dirs=[np.get_include()], 28 | ) 29 | low_level = Extension( 30 | "low_level", sources=["low_level.pyx"], include_dirs=[np.get_include()] 31 | ) 32 | 33 | extensions = [extending, distributions, low_level] 34 | 35 | setup(ext_modules=cythonize(extensions)) 36 | -------------------------------------------------------------------------------- /randomgen/hc128.pxd: -------------------------------------------------------------------------------- 1 | 2 | # coding=utf-8 3 | cimport numpy as np 4 | from libc.stdint cimport uint32_t, uint64_t 5 | 6 | from randomgen.common cimport ( 7 | BitGenerator, 8 | check_state_array, 9 | fully_qualified_name, 10 | int_to_array, 11 | object_to_int, 12 | view_little_endian, 13 | ) 14 | 15 | 16 | cdef extern from "src/hc-128/hc-128.h": 17 | 18 | struct HC128_STATE_T: 19 | uint32_t p[512] 20 | uint32_t q[512] 21 | uint32_t buffer[16] 22 | int hc_idx 23 | int buffer_idx 24 | 25 | ctypedef HC128_STATE_T hc128_state_t 26 | 27 | uint32_t hc128_next32(hc128_state_t *state) noexcept nogil 28 | uint64_t hc128_next64(hc128_state_t *state) noexcept nogil 29 | double hc128_next_double(hc128_state_t *state) noexcept nogil 30 | void hc128_seed(hc128_state_t *state, uint32_t *seed) 31 | 32 | 33 | cdef class HC128(BitGenerator): 34 | 35 | cdef hc128_state_t rng_state 36 | -------------------------------------------------------------------------------- /randomgen/hc128.pyi: -------------------------------------------------------------------------------- 1 | from collections.abc import Sequence 2 | 3 | import numpy as np 4 | 5 | from randomgen.common import BitGenerator 6 | from randomgen.typing import IntegerSequenceSeed, SeedMode 7 | 8 | class HC128(BitGenerator): 9 | def __init__( 10 | self, 11 | seed: IntegerSequenceSeed | None = ..., 12 | *, 13 | key: int | Sequence[int] | None = ..., 14 | mode: SeedMode = ... 15 | ) -> None: ... 16 | def seed( 17 | self, 18 | seed: IntegerSequenceSeed | None = ..., 19 | key: int | Sequence[int] | None = ..., 20 | ) -> None: ... 21 | @property 22 | def state(self) -> dict[str, str | dict[str, int | np.ndarray]]: ... 23 | @state.setter 24 | def state(self, value: dict[str, str | dict[str, int | np.ndarray]]) -> None: ... 25 | -------------------------------------------------------------------------------- /randomgen/jsf.pxd: -------------------------------------------------------------------------------- 1 | 2 | 3 | cimport numpy as np 4 | from libc.stdint cimport uint32_t, uint64_t 5 | 6 | from randomgen.common cimport BitGenerator, fully_qualified_name, uint64_to_double 7 | 8 | 9 | cdef extern from "src/jsf/jsf.h": 10 | 11 | union JSF_UINT_T: 12 | uint64_t u64 13 | uint32_t u32 14 | ctypedef JSF_UINT_T jsf_uint_t 15 | 16 | struct JSF_STATE_T: 17 | jsf_uint_t a 18 | jsf_uint_t b 19 | jsf_uint_t c 20 | jsf_uint_t d 21 | int p 22 | int q 23 | int r 24 | int has_uint32 25 | uint32_t uinteger 26 | 27 | ctypedef JSF_STATE_T jsf_state_t 28 | 29 | uint64_t jsf64_next64(jsf_state_t *state) noexcept nogil 30 | uint32_t jsf64_next32(jsf_state_t *state) noexcept nogil 31 | double jsf64_next_double(jsf_state_t *state) noexcept nogil 32 | void jsf64_seed(jsf_state_t *state, uint64_t *seed, int size) 33 | 34 | uint64_t jsf32_next64(jsf_state_t *state) noexcept nogil 35 | uint32_t jsf32_next32(jsf_state_t *state) noexcept nogil 36 | double jsf32_next_double(jsf_state_t *state) noexcept nogil 37 | void jsf32_seed(jsf_state_t *state, uint32_t *seed, int size) 38 | 39 | 40 | cdef class JSF(BitGenerator): 41 | 42 | cdef jsf_state_t rng_state 43 | cdef int size 44 | cdef int seed_size 45 | cdef setup_generator(self, object p, object q, object r) 46 | cdef _reset_state_variables(self) 47 | -------------------------------------------------------------------------------- /randomgen/jsf.pyi: -------------------------------------------------------------------------------- 1 | from randomgen.common import BitGenerator 2 | from randomgen.typing import IntegerSequenceSeed, SeedMode 3 | 4 | class JSF(BitGenerator): 5 | def __init__( 6 | self, 7 | seed: IntegerSequenceSeed | None = ..., 8 | *, 9 | seed_size: int = ..., 10 | size: int = ..., 11 | p: int | None = ..., 12 | q: int | None = ..., 13 | r: int | None = ..., 14 | mode: SeedMode | None = ... 15 | ) -> None: ... 16 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 17 | @property 18 | def state(self) -> dict[str, str | int | dict[str, int]]: ... 19 | @state.setter 20 | def state(self, value: dict[str, str | int | dict[str, int]]) -> None: ... 21 | -------------------------------------------------------------------------------- /randomgen/legacy/__init__.py: -------------------------------------------------------------------------------- 1 | from randomgen.mtrand import RandomState as LegacyGenerator 2 | 3 | __all__ = ["LegacyGenerator"] 4 | -------------------------------------------------------------------------------- /randomgen/legacy/bounded_integers.pxd.in: -------------------------------------------------------------------------------- 1 | from libc.stdint cimport ( 2 | int8_t, 3 | int16_t, 4 | int32_t, 5 | int64_t, 6 | intptr_t, 7 | uint8_t, 8 | uint16_t, 9 | uint32_t, 10 | uint64_t, 11 | ) 12 | 13 | import numpy as np 14 | 15 | cimport numpy as np 16 | 17 | ctypedef np.npy_bool bool_t 18 | 19 | from randomgen.legacy.distributions cimport aug_bitgen_t 20 | 21 | 22 | cdef inline uint64_t _gen_mask(uint64_t max_val) noexcept nogil: 23 | """Mask generator for use in bounded random numbers""" 24 | # Smallest bit mask >= max 25 | cdef uint64_t mask = max_val 26 | mask |= mask >> 1 27 | mask |= mask >> 2 28 | mask |= mask >> 4 29 | mask |= mask >> 8 30 | mask |= mask >> 16 31 | mask |= mask >> 32 32 | return mask 33 | {{ 34 | py: 35 | inttypes = ("uint64","uint32","uint16","uint8","bool","int64","int32","int16","int8") 36 | }} 37 | {{for inttype in inttypes}} 38 | cdef object _legacy_rand_{{inttype}}(object low, object high, object size, aug_bitgen_t *aug_state, object lock) 39 | {{endfor}} 40 | -------------------------------------------------------------------------------- /randomgen/lxm.pxd: -------------------------------------------------------------------------------- 1 | 2 | 3 | cimport numpy as np 4 | from libc.stdint cimport uint32_t, uint64_t 5 | 6 | from randomgen.common cimport ( 7 | BitGenerator, 8 | check_state_array, 9 | fully_qualified_name, 10 | uint64_to_double, 11 | ) 12 | 13 | 14 | cdef extern from "src/lxm/lxm.h": 15 | 16 | struct LXM_STATE_T: 17 | uint64_t x[4] 18 | uint64_t lcg_state 19 | uint64_t b 20 | int has_uint32 21 | uint32_t uinteger 22 | 23 | ctypedef LXM_STATE_T lxm_state_t 24 | 25 | uint64_t lxm_next64(lxm_state_t *state) noexcept nogil 26 | uint32_t lxm_next32(lxm_state_t *state) noexcept nogil 27 | double lxm_next_double(lxm_state_t *state) noexcept nogil 28 | void lxm_jump(lxm_state_t *state) noexcept nogil 29 | 30 | cdef class LXM(BitGenerator): 31 | 32 | cdef lxm_state_t rng_state 33 | cdef _reset_state_variables(self) 34 | cdef jump_inplace(self, np.npy_intp iter) 35 | -------------------------------------------------------------------------------- /randomgen/lxm.pyi: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed 5 | 6 | class LXM(BitGenerator): 7 | def __init__( 8 | self, seed: IntegerSequenceSeed | None = ..., *, b: int = ... 9 | ) -> None: ... 10 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 11 | def jump(self, iter: int = ...) -> LXM: ... 12 | def jumped(self, iter: int = ...) -> LXM: ... 13 | @property 14 | def state( 15 | self, 16 | ) -> dict[str, str | int | dict[str, int | np.ndarray]]: ... 17 | @state.setter 18 | def state( 19 | self, value: dict[str, str | int | dict[str, int | np.ndarray]] 20 | ) -> None: ... 21 | -------------------------------------------------------------------------------- /randomgen/mt19937.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport uint32_t, uint64_t 3 | 4 | from randomgen.common cimport BitGenerator, check_state_array, fully_qualified_name 5 | 6 | 7 | cdef extern from "src/mt19937/mt19937.h": 8 | 9 | struct MT19937_STATE_T: 10 | uint32_t key[624] 11 | int pos 12 | 13 | ctypedef MT19937_STATE_T mt19937_state_t 14 | 15 | uint64_t mt19937_next64(mt19937_state_t *state) noexcept nogil 16 | uint32_t mt19937_next32(mt19937_state_t *state) noexcept nogil 17 | double mt19937_next_double(mt19937_state_t *state) noexcept nogil 18 | void mt19937_init_by_array(mt19937_state_t *state, uint32_t *init_key, int key_length) 19 | void mt19937_seed(mt19937_state_t *state, uint32_t seed) 20 | void mt19937_jump(mt19937_state_t *state) 21 | void mt19937_jump_default(mt19937_state_t *state) 22 | void mt19937_jump_n(mt19937_state_t *state, int count) 23 | 24 | enum: 25 | RK_STATE_LEN 26 | 27 | cdef class MT19937(BitGenerator): 28 | 29 | cdef mt19937_state_t rng_state 30 | cdef jump_inplace(self, int jumps) 31 | -------------------------------------------------------------------------------- /randomgen/mt19937.pyi: -------------------------------------------------------------------------------- 1 | from typing import Literal 2 | 3 | import numpy as np 4 | 5 | from randomgen.common import BitGenerator 6 | from randomgen.typing import IntegerSequenceSeed 7 | 8 | class MT19937(BitGenerator): 9 | def __init__( 10 | self, 11 | seed: IntegerSequenceSeed | None = ..., 12 | *, 13 | mode: Literal["numpy", "sequence"] | None = ... 14 | ) -> None: ... 15 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 16 | def jump(self, jumps: int = ...) -> MT19937: ... 17 | def jumped(self, jumps: int = ...) -> MT19937: ... 18 | @property 19 | def state(self) -> dict[str, str | dict[str, int | np.ndarray]]: ... 20 | @state.setter 21 | def state( 22 | self, 23 | value: ( 24 | tuple[str, np.ndarray, int] | dict[str, str | dict[str, int | np.ndarray]] 25 | ), 26 | ) -> None: ... 27 | def _jump_tester(self) -> MT19937: ... 28 | -------------------------------------------------------------------------------- /randomgen/mt64.pxd: -------------------------------------------------------------------------------- 1 | 2 | 3 | cimport numpy as np 4 | from libc.stdint cimport uint32_t, uint64_t 5 | 6 | from randomgen.common cimport ( 7 | BitGenerator, 8 | check_state_array, 9 | fully_qualified_name, 10 | uint64_to_double, 11 | ) 12 | 13 | 14 | cdef extern from "src/mt64/mt64.h": 15 | 16 | struct MT64_STATE_T: 17 | uint64_t mt[312] 18 | int mti 19 | int has_uint32 20 | uint32_t uinteger 21 | 22 | ctypedef MT64_STATE_T mt64_state_t 23 | 24 | uint64_t mt64_next64(mt64_state_t *state) noexcept nogil 25 | uint32_t mt64_next32(mt64_state_t *state) noexcept nogil 26 | double mt64_next_double(mt64_state_t *state) noexcept nogil 27 | void mt64_init_by_array(mt64_state_t *state, uint64_t *init_key, int key_length) 28 | void mt64_seed(mt64_state_t *state, uint64_t seed) 29 | 30 | cdef class MT64(BitGenerator): 31 | 32 | cdef mt64_state_t rng_state 33 | cdef _reset_state_variables(self) 34 | -------------------------------------------------------------------------------- /randomgen/mt64.pyi: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed, SeedMode 5 | 6 | class MT64(BitGenerator): 7 | def __init__( 8 | self, seed: IntegerSequenceSeed | None = ..., *, mode: SeedMode | None = ... 9 | ) -> None: ... 10 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 11 | @property 12 | def state( 13 | self, 14 | ) -> dict[str, str | int | dict[str, int | np.ndarray]]: ... 15 | @state.setter 16 | def state( 17 | self, value: dict[str, str | int | dict[str, int | np.ndarray]] 18 | ) -> None: ... 19 | -------------------------------------------------------------------------------- /randomgen/pcg32.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport uint32_t, uint64_t 3 | 4 | from randomgen.common cimport BitGenerator, fully_qualified_name, wrap_int 5 | 6 | 7 | cdef extern from "src/pcg32/pcg32.h": 8 | 9 | cdef struct pcg_state_setseq_64: 10 | uint64_t state 11 | uint64_t inc 12 | 13 | ctypedef pcg_state_setseq_64 pcg32_random_t 14 | 15 | struct PCG32_STATE_T: 16 | pcg32_random_t pcg_state 17 | 18 | ctypedef PCG32_STATE_T pcg32_state_t 19 | 20 | uint64_t pcg32_next64(pcg32_state_t *state) noexcept nogil 21 | uint32_t pcg32_next32(pcg32_state_t *state) noexcept nogil 22 | double pcg32_next_double(pcg32_state_t *state) noexcept nogil 23 | void pcg32_jump(pcg32_state_t *state) 24 | void pcg32_advance_state(pcg32_state_t *state, uint64_t step) 25 | void pcg32_set_seed(pcg32_state_t *state, uint64_t seed, uint64_t inc) 26 | 27 | 28 | cdef class PCG32(BitGenerator): 29 | cdef pcg32_state_t rng_state 30 | cdef jump_inplace(self, object iter) 31 | -------------------------------------------------------------------------------- /randomgen/pcg32.pyi: -------------------------------------------------------------------------------- 1 | from randomgen.common import BitGenerator 2 | from randomgen.typing import IntegerSequenceSeed, SeedMode 3 | 4 | class PCG32(BitGenerator): 5 | def __init__( 6 | self, 7 | seed: IntegerSequenceSeed | None = ..., 8 | inc: int = ..., 9 | *, 10 | mode: SeedMode | None = ... 11 | ) -> None: ... 12 | def seed(self, seed: IntegerSequenceSeed | None = ..., inc: int = ...) -> None: ... 13 | @property 14 | def state(self) -> dict[str, str | dict[str, int]]: ... 15 | @state.setter 16 | def state(self, value: dict[str, str | dict[str, int]]) -> None: ... 17 | def advance(self, delta: int) -> None: ... 18 | def jump(self, iter: int = ...) -> PCG32: ... 19 | def jumped(self, iter: int = ...) -> PCG32: ... 20 | -------------------------------------------------------------------------------- /randomgen/philox.pyi: -------------------------------------------------------------------------------- 1 | from typing import Literal 2 | 3 | import numpy as np 4 | 5 | from randomgen.common import BitGenerator 6 | from randomgen.typing import IntegerSequenceSeed 7 | 8 | class Philox(BitGenerator): 9 | def __init__( 10 | self, 11 | seed: IntegerSequenceSeed | None = ..., 12 | *, 13 | counter: int | np.ndarray | None = ..., 14 | key: int | np.ndarray | None = ..., 15 | number: int = ..., 16 | width: int = ..., 17 | mode: Literal["sequence", "numpy"] | None = ... 18 | ) -> None: ... 19 | def seed( 20 | self, 21 | seed: IntegerSequenceSeed | None = ..., 22 | counter: int | np.ndarray | None = ..., 23 | key: int | np.ndarray | None = ..., 24 | ) -> None: ... 25 | @property 26 | def state( 27 | self, 28 | ) -> dict[str, str | int | np.ndarray | dict[str, np.ndarray]]: ... 29 | @state.setter 30 | def state( 31 | self, value: dict[str, str | int | np.ndarray | dict[str, np.ndarray]] 32 | ) -> None: ... 33 | def jump(self, iter: int = ...) -> Philox: ... 34 | def jumped(self, iter: int = ...) -> Philox: ... 35 | def advance(self, delta: int, counter: bool | None = ...) -> Philox: ... 36 | -------------------------------------------------------------------------------- /randomgen/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bashtage/randomgen/34bc41ac41b94a0df9806fdd4ed242531b520e3a/randomgen/py.typed -------------------------------------------------------------------------------- /randomgen/rdrand.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport uint32_t, uint64_t 3 | 4 | from randomgen.common cimport BitGenerator, fully_qualified_name, uint64_to_double 5 | 6 | DEF BUFFER_SIZE = 256 7 | 8 | cdef extern from "src/rdrand/rdrand.h": 9 | 10 | struct s_rdrand_state: 11 | uint64_t buffer[BUFFER_SIZE] 12 | int buffer_loc 13 | int status 14 | int retries 15 | uint64_t weyl_seq 16 | 17 | ctypedef s_rdrand_state rdrand_state 18 | 19 | int rdrand_fill_buffer(rdrand_state *state) noexcept nogil 20 | int rdrand_next64(rdrand_state *state, uint64_t *val) noexcept nogil 21 | int rdrand_capable() -------------------------------------------------------------------------------- /randomgen/rdrand.pyi: -------------------------------------------------------------------------------- 1 | from threading import Lock 2 | from types import TracebackType 3 | 4 | import numpy as np 5 | 6 | from randomgen.common import BitGenerator 7 | 8 | class RaisingLock: 9 | lock: Lock 10 | def acquire(self, blocking: bool = ..., timeout: int = ...) -> None: ... 11 | def release(self) -> None: ... 12 | def __enter__(self) -> None: ... 13 | def __exit__( 14 | self, 15 | type: type[BaseException] | None, 16 | value: BaseException | None, 17 | traceback: TracebackType | None, 18 | ) -> None: ... 19 | 20 | class RDRAND(BitGenerator): 21 | def __init__(self, seed: None = ..., *, retries: int = ...) -> None: ... 22 | @property 23 | def success(self) -> bool: ... 24 | def seed(self, seed: None = ...) -> None: ... 25 | def random_raw( 26 | self, size: int | None = ..., output: bool = ... 27 | ) -> int | np.ndarray | None: ... 28 | def jumped(self, iter: int = ...) -> RDRAND: ... 29 | @property 30 | def state(self) -> dict[str, str | int | np.ndarray]: ... 31 | @state.setter 32 | def state(self, value: dict[str, str | int | np.ndarray]) -> None: ... 33 | -------------------------------------------------------------------------------- /randomgen/romu.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport uint32_t, uint64_t 3 | 4 | from randomgen.common cimport BitGenerator, fully_qualified_name, uint64_to_double 5 | 6 | 7 | cdef extern from "src/romu/romu.h": 8 | 9 | struct ROMU_STATE_T: 10 | uint64_t w 11 | uint64_t x 12 | uint64_t y 13 | uint64_t z 14 | int has_uint32 15 | uint32_t uinteger 16 | 17 | ctypedef ROMU_STATE_T romu_state_t 18 | 19 | uint64_t romuquad_next64(romu_state_t *state) noexcept nogil 20 | uint32_t romuquad_next32(romu_state_t *state) noexcept nogil 21 | uint64_t romutrio_next64(romu_state_t *state) noexcept nogil 22 | uint32_t romutrio_next32(romu_state_t *state) noexcept nogil 23 | void romu_seed(romu_state_t *state, uint64_t w, uint64_t x, uint64_t y, uint64_t z, int quad) 24 | 25 | 26 | cdef class Romu(BitGenerator): 27 | 28 | cdef readonly object variant 29 | cdef romu_state_t rng_state 30 | cdef _reset_state_variables(self) 31 | cdef _check_variant(self, variant) 32 | cdef _setup_bitgen(self) 33 | -------------------------------------------------------------------------------- /randomgen/romu.pyi: -------------------------------------------------------------------------------- 1 | from typing import Literal 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed 5 | 6 | class Romu(BitGenerator): 7 | def __init__( 8 | self, 9 | seed: IntegerSequenceSeed | None = ..., 10 | variant: Literal["trio", "quad"] = ..., 11 | ) -> None: ... 12 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 13 | @property 14 | def state(self) -> dict[str, str | int | dict[str, int]]: ... 15 | @state.setter 16 | def state(self, value: dict[str, str | int | dict[str, int]]) -> None: ... 17 | -------------------------------------------------------------------------------- /randomgen/seed_sequence.py: -------------------------------------------------------------------------------- 1 | try: 2 | from numpy.random._bit_generator import ( 3 | ISeedSequence, 4 | ISpawnableSeedSequence, 5 | SeedlessSeedSequence, 6 | SeedSequence, 7 | ) 8 | except (ImportError, AttributeError): 9 | try: 10 | from numpy.random.bit_generator import ( 11 | ISeedSequence, 12 | ISpawnableSeedSequence, 13 | SeedlessSeedSequence, 14 | SeedSequence, 15 | ) 16 | except (ImportError, AttributeError): 17 | from randomgen._seed_sequence import ( 18 | ISeedSequence, 19 | ISpawnableSeedSequence, 20 | SeedlessSeedSequence, 21 | SeedSequence, 22 | ) 23 | 24 | __all__ = [ 25 | "SeedSequence", 26 | "SeedlessSeedSequence", 27 | "ISeedSequence", 28 | "ISpawnableSeedSequence", 29 | ] 30 | -------------------------------------------------------------------------------- /randomgen/sfc.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport int8_t, uint8_t, uint32_t, uint64_t 3 | 4 | from randomgen.common cimport BitGenerator, fully_qualified_name, uint64_to_double 5 | 6 | 7 | cdef extern from "src/sfc/sfc.h": 8 | 9 | struct SFC_STATE_T: 10 | uint64_t a 11 | uint64_t b 12 | uint64_t c 13 | uint64_t w 14 | uint64_t k 15 | int has_uint32 16 | uint32_t uinteger 17 | 18 | ctypedef SFC_STATE_T sfc_state_t 19 | 20 | uint64_t sfc_next64(sfc_state_t *state) noexcept nogil 21 | uint32_t sfc_next32(sfc_state_t *state) noexcept nogil 22 | void sfc_seed(sfc_state_t *state, uint64_t *seed, uint64_t w, uint64_t k) 23 | 24 | cdef class SFC64(BitGenerator): 25 | 26 | cdef object k, w 27 | cdef sfc_state_t rng_state 28 | cdef _reset_state_variables(self) 29 | cdef uint64_t generate_bits(self, int8_t bits) 30 | -------------------------------------------------------------------------------- /randomgen/sfc.pyi: -------------------------------------------------------------------------------- 1 | from typing import Literal 2 | 3 | import numpy as np 4 | 5 | from randomgen.common import BitGenerator 6 | from randomgen.typing import IntegerSequenceSeed 7 | 8 | class SFC64(BitGenerator): 9 | def __init__( 10 | self, 11 | seed: IntegerSequenceSeed | None = ..., 12 | w: int = ..., 13 | k: int = ..., 14 | *, 15 | mode: Literal["sequence", "numpy"] | None 16 | ) -> None: ... 17 | def weyl_increments( 18 | self, n: int, max_bits: int = ..., min_bits: int | None = ... 19 | ) -> np.ndarray: ... 20 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 21 | @property 22 | def state(self) -> dict[str, str | int | dict[str, int]]: ... 23 | @state.setter 24 | def state(self, value: dict[str, str | int | dict[str, int]]) -> None: ... 25 | -------------------------------------------------------------------------------- /randomgen/sfmt.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport uint32_t, uint64_t 3 | 4 | from randomgen.common cimport ( 5 | BitGenerator, 6 | PyArray_calloc_aligned, 7 | PyArray_free_aligned, 8 | PyArray_malloc_aligned, 9 | check_state_array, 10 | fully_qualified_name, 11 | uint64_to_double, 12 | ) 13 | 14 | DEF SFMT_MEXP = 19937 15 | DEF SFMT_N = 156 # SFMT_MEXP / 128 + 1 16 | DEF SFMT_N64 = SFMT_N * 2 17 | 18 | cdef extern from "src/sfmt/sfmt.h": 19 | 20 | union W128_T: 21 | uint32_t u[4] 22 | uint64_t u64[2] 23 | 24 | ctypedef W128_T w128_t 25 | 26 | struct SFMT_T: 27 | w128_t state[SFMT_N] 28 | int idx 29 | 30 | ctypedef SFMT_T sfmt_t 31 | 32 | struct SFMT_STATE_T: 33 | sfmt_t *state 34 | int has_uint32 35 | uint32_t uinteger 36 | 37 | uint64_t *buffered_uint64 38 | int buffer_loc 39 | 40 | ctypedef SFMT_STATE_T sfmt_state_t 41 | 42 | uint64_t sfmt_next64(sfmt_state_t *state) noexcept nogil 43 | uint32_t sfmt_next32(sfmt_state_t *state) noexcept nogil 44 | 45 | void sfmt_init_gen_rand(sfmt_t * sfmt, uint32_t seed) 46 | void sfmt_init_by_array(sfmt_t * sfmt, uint32_t *init_key, int key_length) 47 | void sfmt_jump(sfmt_state_t *state) 48 | void sfmt_jump_n(sfmt_state_t *state, int count) 49 | 50 | cdef class SFMT(BitGenerator): 51 | 52 | cdef sfmt_state_t rng_state 53 | cdef _reset_state_variables(self) 54 | cdef jump_inplace(self, object iter) 55 | -------------------------------------------------------------------------------- /randomgen/sfmt.pyi: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed, SeedMode 5 | 6 | class SFMT(BitGenerator): 7 | def __init__( 8 | self, seed: IntegerSequenceSeed | None = ..., *, mode: SeedMode | None = ... 9 | ) -> None: ... 10 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 11 | def jump(self, iter: int = ...) -> SFMT: ... 12 | def jumped(self, iter: int = ...) -> SFMT: ... 13 | @property 14 | def state( 15 | self, 16 | ) -> dict[str, str | int | np.ndarray | dict[str, int | np.ndarray]]: ... 17 | @state.setter 18 | def state( 19 | self, 20 | value: dict[str, str | int | np.ndarray | dict[str, int | np.ndarray]], 21 | ) -> None: ... 22 | -------------------------------------------------------------------------------- /randomgen/speck128.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport uint8_t, uint32_t, uint64_t 3 | 4 | from randomgen.common cimport ( 5 | BitGenerator, 6 | PyArray_calloc_aligned, 7 | PyArray_free_aligned, 8 | check_state_array, 9 | fully_qualified_name, 10 | int_to_array, 11 | object_to_int, 12 | uint64_to_double, 13 | wrap_int, 14 | ) 15 | 16 | DEF SPECK_UNROLL = 12 17 | DEF SPECK_ROUNDS = 34 18 | 19 | cdef extern from "src/speck-128/speck-128.h": 20 | 21 | union SPEC_T: 22 | uint64_t u64[2] 23 | 24 | ctypedef SPEC_T spec_t 25 | 26 | struct SPECK_STATE_T: 27 | spec_t round_key[SPECK_ROUNDS] 28 | spec_t ctr[SPECK_UNROLL // 2] 29 | uint8_t buffer[8 * SPECK_UNROLL] 30 | int rounds 31 | 32 | int offset 33 | int has_uint32 34 | uint32_t uinteger 35 | 36 | ctypedef SPECK_STATE_T speck_state_t 37 | 38 | uint64_t speck_next64(speck_state_t *state) noexcept nogil 39 | uint32_t speck_next32(speck_state_t *state) noexcept nogil 40 | 41 | int RANDOMGEN_USE_SSE41 42 | int speck_sse41_capable() 43 | void speck_use_sse41(int val) 44 | void speck_seed(speck_state_t *state, uint64_t *seed) 45 | void speck_set_counter(speck_state_t *state, uint64_t *ctr) 46 | void speck_advance(speck_state_t *state, uint64_t *step) 47 | 48 | 49 | cdef class SPECK128(BitGenerator): 50 | 51 | cdef speck_state_t *rng_state 52 | cdef _reset_state_variables(self) 53 | cdef jump_inplace(self, object iter) 54 | -------------------------------------------------------------------------------- /randomgen/speck128.pyi: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed, SeedMode 5 | 6 | SPECK_MAX_ROUNDS: int 7 | 8 | class SPECK128(BitGenerator): 9 | def __init__( 10 | self, 11 | seed: IntegerSequenceSeed | None = ..., 12 | *, 13 | counter: int | np.ndarray | None = ..., 14 | key: int | np.ndarray | None = ..., 15 | rounds: int = ..., 16 | mode: SeedMode | None = ... 17 | ) -> None: ... 18 | def seed( 19 | self, 20 | seed: IntegerSequenceSeed | None = ..., 21 | counter: int | np.ndarray | None = ..., 22 | key: int | np.ndarray | None = ..., 23 | ) -> None: ... 24 | @property 25 | def use_sse41(self) -> bool: ... 26 | @use_sse41.setter 27 | def use_sse41(self, value: bool) -> None: ... 28 | @property 29 | def state( 30 | self, 31 | ) -> dict[str, str | int | dict[str, int | np.ndarray]]: ... 32 | @state.setter 33 | def state( 34 | self, value: dict[str, str | int | dict[str, int | np.ndarray]] 35 | ) -> None: ... 36 | def jump(self, iter: int = ...) -> SPECK128: ... 37 | def jumped(self, iter: int = ...) -> SPECK128: ... 38 | def advance(self, delta: int) -> SPECK128: ... 39 | -------------------------------------------------------------------------------- /randomgen/squares.pxd: -------------------------------------------------------------------------------- 1 | 2 | 3 | cimport numpy as np 4 | from libc.stdint cimport uint32_t, uint64_t 5 | 6 | from randomgen.common cimport BitGenerator, fully_qualified_name 7 | 8 | 9 | cdef extern from "src/squares/squares.h": 10 | 11 | struct SQUARES_STATE_T: 12 | uint64_t key 13 | uint64_t counter 14 | int has_uint32 15 | uint32_t uinteger 16 | 17 | ctypedef SQUARES_STATE_T squares_state_t 18 | 19 | uint64_t squares_next64(squares_state_t *state) noexcept nogil 20 | uint32_t squares_next32(squares_state_t *state) noexcept nogil 21 | double squares_next_double(squares_state_t *state) noexcept nogil 22 | uint64_t squares_32_next64(squares_state_t *state) noexcept nogil 23 | uint32_t squares_32_next32(squares_state_t *state) noexcept nogil 24 | double squares_32_next_double(squares_state_t *state) noexcept nogil 25 | 26 | cdef class Squares(BitGenerator): 27 | cdef squares_state_t rng_state 28 | cdef void _setup_bitgen(self) 29 | cdef int variant 30 | cdef bint _use64 31 | cdef uint64_t _check_value(self, object val, object name, bint odd) 32 | cdef void _reset_state_variables(self) 33 | 34 | -------------------------------------------------------------------------------- /randomgen/src/aligned_malloc/aligned_malloc.c: -------------------------------------------------------------------------------- 1 | #include "aligned_malloc.h" 2 | 3 | static NPY_INLINE void *PyArray_realloc_aligned(void *p, size_t n); 4 | 5 | static NPY_INLINE void *PyArray_malloc_aligned(size_t n); 6 | 7 | static NPY_INLINE void *PyArray_calloc_aligned(size_t n, size_t s); 8 | 9 | static NPY_INLINE void PyArray_free_aligned(void *p); -------------------------------------------------------------------------------- /randomgen/src/aligned_malloc/aligned_malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__ALIGNED_MALLOC_H_ 2 | #define _RANDOMDGEN__ALIGNED_MALLOC_H_ 3 | 4 | #include "Python.h" 5 | #include "numpy/npy_common.h" 6 | 7 | #define NPY_MEMALIGN 64 /* 16 for SSE2, 32 for AVX, 64 for Xeon Phi */ 8 | 9 | static NPY_INLINE void *PyArray_realloc_aligned(void *p, size_t n) 10 | { 11 | void *p1, **p2, *base; 12 | size_t old_offs, offs = NPY_MEMALIGN - 1 + sizeof(void *); 13 | if (NPY_UNLIKELY(p != NULL)) 14 | { 15 | base = *(((void **)p) - 1); 16 | if (NPY_UNLIKELY((p1 = PyMem_Realloc(base, n + offs)) == NULL)) 17 | return NULL; 18 | if (NPY_LIKELY(p1 == base)) 19 | return p; 20 | p2 = (void **)(((Py_uintptr_t)(p1) + offs) & ~(NPY_MEMALIGN - 1)); 21 | old_offs = (size_t)((Py_uintptr_t)p - (Py_uintptr_t)base); 22 | memmove((void *)p2, ((char *)p1) + old_offs, n); 23 | } 24 | else 25 | { 26 | if (NPY_UNLIKELY((p1 = PyMem_Malloc(n + offs)) == NULL)) 27 | return NULL; 28 | p2 = (void **)(((Py_uintptr_t)(p1) + offs) & ~(NPY_MEMALIGN - 1)); 29 | } 30 | *(p2 - 1) = p1; 31 | return (void *)p2; 32 | } 33 | 34 | static NPY_INLINE void *PyArray_malloc_aligned(size_t n) 35 | { 36 | return PyArray_realloc_aligned(NULL, n); 37 | } 38 | 39 | static NPY_INLINE void *PyArray_calloc_aligned(size_t n, size_t s) 40 | { 41 | void *p; 42 | if (NPY_UNLIKELY((p = PyArray_realloc_aligned(NULL, n * s)) == NULL)) 43 | return NULL; 44 | memset(p, 0, n * s); 45 | return p; 46 | } 47 | 48 | static NPY_INLINE void PyArray_free_aligned(void *p) 49 | { 50 | void *base = *(((void **)p) - 1); 51 | PyMem_Free(base); 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /randomgen/src/chacha/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Orson Peters 2 | 3 | This software is provided 'as-is', without any express or implied warranty. In no event will the 4 | authors be held liable for any damages arising from the use of this software. 5 | 6 | Permission is granted to anyone to use this software for any purpose, including commercial 7 | applications, and to alter it and redistribute it freely, subject to the following restrictions: 8 | 9 | 1. The origin of this software must not be misrepresented; you must not claim that you wrote the 10 | original software. If you use this software in a product, an acknowledgment in the product 11 | documentation would be appreciated but is not required. 12 | 13 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as 14 | being the original software. 15 | 16 | 3. This notice may not be removed or altered from any source distribution. 17 | -------------------------------------------------------------------------------- /randomgen/src/chacha/chacha-benchmark.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // g++ -benchmark.cpp -mssse3 -O2 -o -benchmark 3 | // ./-benchmark 4 | // 5 | // cl /Ox /EHsc -benchmark.cpp 6 | // ./-benchmark.exe 7 | // 8 | 9 | #include ".orig.h" 10 | #include 11 | using namespace std; 12 | 13 | #define N 1000000000 14 | 15 | int main() { 16 | clock_t t1, t2; 17 | 18 | auto chacha = ChaCha<20>(0xDEADBEEF); 19 | uint64_t sum = 0; 20 | t1 = clock(); 21 | for (int i = 0; i < N; i++) { 22 | sum += ((uint64_t)chacha()) << 32 | chacha(); 23 | } 24 | t2 = clock(); 25 | cout << sum << std::endl; 26 | double diff = (double)(t2) - (double)(t1); 27 | double seconds = diff / CLOCKS_PER_SEC; 28 | double num_per_second = (double)N / seconds; 29 | cout.precision(10); 30 | cout << num_per_second << " randoms per second\n"; 31 | cout.precision(3); 32 | cout << 1000. * 1000000. / num_per_second << " ms to produce 1,000,000 draws \n"; 33 | } 34 | -------------------------------------------------------------------------------- /randomgen/src/chacha/chacha-test-data-gen.cpp: -------------------------------------------------------------------------------- 1 | #include "chacha.orig.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | #define N 1000 10 | 11 | int main() { 12 | clock_t t1, t2; 13 | uint64_t store[N]; 14 | uint64_t seedval[2] = {15793235383387715774ULL, 12390638538380655177ULL}; 15 | uint64_t stream[2] = {2361836109651742017ULL,3188717715514472916ULL}; 16 | auto chacha = ChaCha<20>(seedval, stream); 17 | std::ofstream ofile; 18 | ofile.open ("chacha-testset-1.csv"); 19 | ofile << "seed, " << 0 <(seedval, stream); 35 | ofile.open ("chacha-testset-2.csv"); 36 | ofile << "seed, " << 0xDEADBEAF <= 1) 12 | { 13 | __get_cpuid(1, &eax, &ebx, &ecx, &edx); 14 | } 15 | #elif defined(_MSC_VER) && defined(_WIN32) 16 | int cpu_info[4] = {0}; 17 | int num_ids, reg = 0, eax = 0, ebx = 0, ecx = 0, edx = 0; 18 | __cpuid(cpu_info, 0); 19 | num_ids = (int)cpu_info[0]; 20 | if (num_ids >= 1) 21 | { 22 | __cpuidex(cpu_info, 1, 0); 23 | eax = cpu_info[0]; 24 | ebx = cpu_info[1]; 25 | ecx = cpu_info[2]; 26 | edx = cpu_info[3]; 27 | } 28 | #endif 29 | #else 30 | uint32_t reg, eax, ebx, ecx, edx; 31 | reg = 0; eax = 0; ebx = 0; ecx = 0; edx = 0; 32 | #endif 33 | switch(major){ 34 | case 0: 35 | reg = eax; 36 | break; 37 | 38 | case 1: 39 | reg = ebx; 40 | break; 41 | 42 | case 2: 43 | reg = ecx; 44 | break; 45 | 46 | case 3: 47 | reg = edx; 48 | break; 49 | } 50 | for (i = 0; i < 32; i++) 51 | { 52 | flags[i] = (reg >> i) & 0x1; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /randomgen/src/common/cpu_features.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMGEN_CPU_FEATURES_H_ 2 | #define _RANDOMGEN_CPU_FEATURES_H_ 3 | 4 | #include "randomgen_config.h" 5 | 6 | #define RANDOMGEN_EAX 0 7 | #define RANDOMGEN_EBX 1 8 | #define RANDOMGEN_ECX 2 9 | #define RANDOMGEN_EDX 3 10 | 11 | #undef HAVE_CPUID 12 | #if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ 13 | defined(_M_IX86) 14 | #if defined(_MSC_VER) && defined(_WIN32) 15 | #if _MSC_VER >= 1500 16 | #define HAVE_CPUID 1 17 | #endif 18 | #else 19 | #define HAVE_CPUID 1 20 | #include 21 | #endif 22 | #endif 23 | 24 | void feature_flags(int flags[32], int major); 25 | 26 | #endif /* _RANDOMGEN_CPU_FEATURES_H */ -------------------------------------------------------------------------------- /randomgen/src/common/randomgen_config.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__CONFIG_H_ 2 | #define _RANDOMDGEN__CONFIG_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #if defined(_WIN32) && defined(_MSC_VER) 10 | 11 | /* windows msvc */ 12 | 13 | #ifndef MSVCFORCEINLINE 14 | #ifndef _DEBUG 15 | #define MSVCFORCEINLINE __forceinline 16 | #else 17 | #define MSVCFORCEINLINE 18 | #endif 19 | #endif 20 | 21 | #ifndef inline 22 | #if _MSC_VER < 1600 23 | /* msvs 2008 and earlier */ 24 | #define inline _inline MSVCFORCEINLINE 25 | #else 26 | /* msvs 2010 and later */ 27 | #define inline __inline MSVCFORCEINLINE 28 | #endif 29 | #define INLINE inline 30 | #else 31 | #define INLINE __inline MSVCFORCEINLINE 32 | #endif 33 | 34 | #if _MSC_VER < 1600 35 | 36 | /* msvs 2008 and earlier */ 37 | #include "inttypes.h" 38 | #include "stdbool.h" 39 | #include "stdint.h" 40 | 41 | #elif _MSC_VER < 1800 42 | 43 | /* msvs 2010-2012 */ 44 | #include "inttypes.h" 45 | #include "stdbool.h" 46 | #include 47 | 48 | #else 49 | 50 | /* msvs 2013 and later */ 51 | #include 52 | #include 53 | #include 54 | 55 | #endif 56 | 57 | #define ALIGN_WINDOWS __declspec(align(16)) 58 | #define ALIGN_GCC_CLANG 59 | 60 | #else 61 | 62 | #include 63 | #include 64 | #include 65 | 66 | #define INLINE inline 67 | 68 | #define ALIGN_WINDOWS 69 | #define ALIGN_GCC_CLANG __attribute__((aligned(16))) 70 | 71 | #endif 72 | 73 | #if defined(__MINGW32__) 74 | #include 75 | #endif 76 | 77 | #ifdef _WIN32 78 | #define UNLIKELY(x) ((x)) 79 | #define LIKELY(x) ((x)) 80 | #else 81 | #define UNLIKELY(x) (__builtin_expect((x), 0)) 82 | #define LIKELY(x) (__builtin_expect((x), 1)) 83 | #endif 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /randomgen/src/common/randomgen_config_numpy.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__CONFIG_NUMPY_H_ 2 | #define _RANDOMDGEN__CONFIG_NUMPY_H_ 3 | 4 | #ifndef RANDOMGEN_STANDALONE 5 | 6 | #include "Python.h" 7 | #include "numpy/npy_common.h" 8 | #include "numpy/npy_math.h" 9 | 10 | #else 11 | 12 | #include "standalone/aligned_malloc.h" 13 | #include "standalone/npy_common.h" 14 | #include "standalone/npy_math.h" 15 | #include "standalone/python.h" 16 | 17 | #endif 18 | 19 | #ifndef NPY_MEMALIGN 20 | 21 | #define NPY_MEMALIGN 64 /* 16 for SSE2, 32 for AVX, 64 for Xeon Phi */ 22 | 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /randomgen/src/common/randomgen_immintrin.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMGEN__IMMINTRIN_H_ 2 | #define _RANDOMGEN__IMMINTRIN_H_ 3 | 4 | #if (defined(_M_IX86_FP) && _M_IX86_FP >= 2) || defined(_M_X64) 5 | #if !defined(__SSE2__) 6 | #define __SSE2__ 1 7 | #endif 8 | #if defined(_MSC_VER) && defined(_WIN32) && _MSC_VER >= 1900 9 | #if !defined(__SSSE3__) 10 | #define __SSSE3__ 1 11 | #endif 12 | #if !defined(__AES__) 13 | #define __AES__ 1 14 | #endif 15 | #if !defined(__RDRND__) 16 | #define __RDRND__ 1 17 | #endif 18 | #endif 19 | #endif 20 | 21 | #if defined(__SSE2__) && __SSE2__ 22 | #include 23 | #endif 24 | 25 | #if (defined(__SSSE3__) && __SSSE3__) || (defined(__AES__) && __AES__) || \ 26 | (defined(__RDRND__) && __RDRND__) 27 | #include 28 | #endif 29 | 30 | #endif /* _RANDOMGEN__IMMINTRIN_H_ */ 31 | -------------------------------------------------------------------------------- /randomgen/src/common/standalone/Python.h: -------------------------------------------------------------------------------- 1 | #ifndef Py_PYTHON_H 2 | #define Py_PYTHON_H 3 | 4 | #include "../randomgen_config.h" 5 | 6 | #include 7 | 8 | typedef uintptr_t Py_uintptr_t; 9 | typedef intptr_t Py_intptr_t; 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /randomgen/src/common/standalone/aligned_malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__ALIGNED_MALLOC_H_ 2 | #define _RANDOMDGEN__ALIGNED_MALLOC_H_ 3 | 4 | #include "../randomgen_config.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | static INLINE void *_aligned_calloc(size_t n, size_t size, size_t alignment) { 11 | 12 | void *p = 0; 13 | 14 | size_t asize = n * size; 15 | 16 | p = _aligned_malloc(asize, alignment); 17 | 18 | if (p) { 19 | memset(p, 0, asize); 20 | } 21 | 22 | return p; 23 | } 24 | 25 | #define malloc_aligned(a) _aligned_calloc(1, (a), NPY_MEMALIGN) 26 | #define calloc_aligned(a, b) _aligned_calloc((a), (b), NPY_MEMALIGN) 27 | #define free_aligned(a) _aligned_free(a) 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /randomgen/src/common/standalone/npy_common.h: -------------------------------------------------------------------------------- 1 | #ifndef _NPY_COMMON_H_ 2 | #define _NPY_COMMON_H_ 3 | 4 | #include "../randomgen_config.h" 5 | 6 | #include "Python.h" 7 | 8 | #include 9 | 10 | #define NPY_INLINE INLINE 11 | 12 | #define NPY_SIZEOF_LONG SIZEOF_LONG 13 | 14 | typedef double npy_double; 15 | 16 | typedef uint32_t npy_uint32; 17 | 18 | typedef unsigned char npy_bool; 19 | #define NPY_FALSE 0 20 | #define NPY_TRUE 1 21 | 22 | typedef Py_intptr_t npy_intp; 23 | typedef Py_uintptr_t npy_uintp; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /randomgen/src/common/standalone/npy_math.h: -------------------------------------------------------------------------------- 1 | #ifndef __NPY_MATH_C99_H_ 2 | #define __NPY_MATH_C99_H_ 3 | 4 | #include "../randomgen_config.h" 5 | 6 | #include "npy_common.h" 7 | 8 | #include 9 | 10 | #if defined(_MSC_VER) && (_MSC_VER < 1900) 11 | #define npy_isnan(x) _isnan((x)) 12 | #else 13 | #define npy_isnan(x) isnan(x) 14 | #endif 15 | 16 | NPY_INLINE static float __npy_nanf(void) { 17 | const union { 18 | npy_uint32 __i; 19 | float __f; 20 | } __bint = {0x7fc00000UL}; 21 | return __bint.__f; 22 | } 23 | 24 | #define NPY_NANF __npy_nanf() 25 | 26 | #define NPY_NAN ((npy_double)NPY_NANF) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /randomgen/src/common/stdbool.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__STDBOOL_H 2 | #define _RANDOMDGEN__STDBOOL_H 3 | 4 | #if defined(_WIN32) && defined(_MSC_VER) 5 | #ifndef __bool_true_false_are_defined 6 | #define __bool_true_false_are_defined 1 7 | typedef unsigned char bool; 8 | #define false 0 9 | #define true 1 10 | #endif 11 | #endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /randomgen/src/distributions/binomial.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bashtage/randomgen/34bc41ac41b94a0df9806fdd4ed242531b520e3a/randomgen/src/distributions/binomial.h -------------------------------------------------------------------------------- /randomgen/src/distributions/logfactorial.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LOGFACTORIAL_H 3 | #define LOGFACTORIAL_H 4 | 5 | #include 6 | 7 | double logfactorial(int64_t k); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /randomgen/src/distributions/loggam.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__LOGGAM_H_ 2 | #define _RANDOMDGEN__LOGGAM_H_ 3 | 4 | /* 5 | * log-gamma function to support some of these distributions. The 6 | * algorithm comes from SPECFUN by Shanjie Zhang and Jianming Jin and their 7 | * book "Computation of Special Functions", 1996, John Wiley & Sons, Inc. 8 | */ 9 | static double loggam(double x) { 10 | double x0, x2, lg2pi, gl, gl0; 11 | RAND_INT_TYPE k, n; 12 | 13 | static double a[10] = {8.333333333333333e-02, -2.777777777777778e-03, 14 | 7.936507936507937e-04, -5.952380952380952e-04, 15 | 8.417508417508418e-04, -1.917526917526918e-03, 16 | 6.410256410256410e-03, -2.955065359477124e-02, 17 | 1.796443723688307e-01, -1.39243221690590e+00}; 18 | 19 | if ((x == 1.0) || (x == 2.0)) { 20 | return 0.0; 21 | } else if (x < 7.0) { 22 | n = (RAND_INT_TYPE)(7 - x); 23 | } else { 24 | n = 0; 25 | } 26 | x0 = x + n; 27 | x2 = (1.0 / x0) * (1.0 / x0); 28 | /* log(2 * M_PI) */ 29 | lg2pi = 1.8378770664093453e+00; 30 | gl0 = a[9]; 31 | for (k = 8; k >= 0; k--) { 32 | gl0 *= x2; 33 | gl0 += a[k]; 34 | } 35 | gl = gl0 / x0 + 0.5 * lg2pi + (x0 - 0.5) * log(x0) - x0; 36 | if (x < 7.0) { 37 | for (k = 1; k <= n; k++) { 38 | gl -= log(x0 - 1.0); 39 | x0 -= 1.0; 40 | } 41 | } 42 | return gl; 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /randomgen/src/distributions/rg-distributions.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__DISTRIBUTIONS_H_ 2 | #define _RANDOMDGEN__DISTRIBUTIONS_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "numpy/random/distributions.h" 9 | #include "../common/randomgen_config_numpy.h" 10 | #include "../common/randomgen_config.h" 11 | 12 | /* 13 | #ifdef DLL_EXPORT 14 | #define DECLDIR __declspec(dllexport) 15 | #else 16 | #define DECLDIR extern 17 | #endif 18 | */ 19 | 20 | /* Inline generators for internal use */ 21 | static NPY_INLINE uint32_t rg_next_uint32(bitgen_t *bitgen_state) { 22 | return bitgen_state->next_uint32(bitgen_state->state); 23 | } 24 | 25 | 26 | static NPY_INLINE uint64_t rg_next_uint64(bitgen_t *bitgen_state) { 27 | return bitgen_state->next_uint64(bitgen_state->state); 28 | } 29 | 30 | /* Inline generators for internal use */ 31 | static NPY_INLINE float rg_next_float(bitgen_t *bitgen_state) { 32 | return (rg_next_uint32(bitgen_state) >> 9) * (1.0f / 8388608.0f); 33 | } 34 | 35 | static NPY_INLINE double rg_next_double(bitgen_t *bitgen_state) { 36 | return bitgen_state->next_double(bitgen_state->state); 37 | } 38 | 39 | 40 | DECLDIR void random_double_fill(bitgen_t *bitgen_state, npy_intp cnt, 41 | double *out); 42 | DECLDIR float random_float(bitgen_t *bitgen_state); 43 | DECLDIR int random_long_double_size(void); 44 | DECLDIR long double random_long_double(bitgen_t *bitgen_state); 45 | DECLDIR void random_long_double_fill(bitgen_t *bitgen_state, npy_intp cnt, 46 | long double *out); 47 | DECLDIR void random_wishart_large_df(bitgen_t *bitgen_state, int64_t df, 48 | npy_intp dim, npy_intp num, double *w, 49 | double *n); 50 | 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /randomgen/src/dsfmt/LICENSE.md: -------------------------------------------------------------------------------- 1 | # DSFMT 2 | 3 | Copyright (c) 2007, 2008, 2009 Mutsuo Saito, Makoto Matsumoto 4 | and Hiroshima University. 5 | Copyright (c) 2011, 2002 Mutsuo Saito, Makoto Matsumoto, Hiroshima 6 | University and The University of Tokyo. 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions are 11 | met: 12 | 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above 16 | copyright notice, this list of conditions and the following 17 | disclaimer in the documentation and/or other materials provided 18 | with the distribution. 19 | * Neither the name of the Hiroshima University nor the names of 20 | its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written 22 | permission. 23 | 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | -------------------------------------------------------------------------------- /randomgen/src/dsfmt/dSFMT-benchmark.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * cl dsfmt-benchmark.c dSFMT.c /Ox -DHAVE_SSE2 4 | * 5 | * gcc dSFMT-benchmark.c dSFMT.c -O3 -DHAVE_SSE2 -DDSFMT_MEXP=19937 -o 6 | * dSFMT-benchmark 7 | */ 8 | #include 9 | #include 10 | 11 | #include "dsfmt.h" 12 | 13 | 14 | #define N 1000000000 15 | 16 | int main() { 17 | int i, j; 18 | uint32_t seed = 0xDEADBEAF; 19 | uint64_t count = 0, sum = 0; 20 | dsfmt_t state; 21 | double buffer[DSFMT_N64]; 22 | 23 | uint64_t out; 24 | uint64_t *tmp; 25 | dsfmt_init_gen_rand(&state, seed); 26 | clock_t begin = clock(); 27 | for (i = 0; i < N / (DSFMT_N64 / 2); i++) { 28 | dsfmt_fill_array_close_open(&state, &buffer[0], DSFMT_N64); 29 | for (j = 0; j < DSFMT_N64; j += 2) { 30 | tmp = (uint64_t *)&buffer[j]; 31 | out = (*tmp >> 16) << 32; 32 | tmp = (uint64_t *)&buffer[j + 1]; 33 | out |= (*tmp >> 16) & 0xffffffff; 34 | sum += out; 35 | count++; 36 | } 37 | } 38 | clock_t end = clock(); 39 | double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 40 | printf("0x%" PRIx64 "\ncount: %" PRIu64 "\n", sum, count); 41 | printf("%" PRIu64 " randoms per second\n", 42 | (uint64_t)(N / time_spent) / 1000000 * 1000000); 43 | } 44 | -------------------------------------------------------------------------------- /randomgen/src/dsfmt/dSFMT-jump.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef DSFMT_JUMP_H 3 | #define DSFMT_JUMP_H 4 | /** 5 | * @file SFMT-jump.h 6 | * 7 | * @brief jump header file. 8 | * 9 | * @author Mutsuo Saito (Hiroshima University) 10 | * @author Makoto Matsumoto (The University of Tokyo) 11 | * 12 | * Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, 13 | * Hiroshima University and The University of Tokyo. 14 | * All rights reserved. 15 | * 16 | * The 3-clause BSD License is applied to this software, see 17 | * LICENSE.txt 18 | */ 19 | #if defined(__cplusplus) 20 | extern "C" { 21 | #endif 22 | 23 | #include "dsfmt.h" 24 | void dSFMT_jump(dsfmt_t *dsfmt, const char *jump_str); 25 | 26 | #if defined(__cplusplus) 27 | } 28 | #endif 29 | #endif 30 | -------------------------------------------------------------------------------- /randomgen/src/dsfmt/dSFMT-params19937.h: -------------------------------------------------------------------------------- 1 | #ifndef DSFMT_PARAMS19937_H 2 | #define DSFMT_PARAMS19937_H 3 | 4 | /* #define DSFMT_N 191 */ 5 | /* #define DSFMT_MAXDEGREE 19992 */ 6 | #define DSFMT_POS1 117 7 | #define DSFMT_SL1 19 8 | #define DSFMT_MSK1 UINT64_C(0x000ffafffffffb3f) 9 | #define DSFMT_MSK2 UINT64_C(0x000ffdfffc90fffd) 10 | #define DSFMT_MSK32_1 0x000ffaffU 11 | #define DSFMT_MSK32_2 0xfffffb3fU 12 | #define DSFMT_MSK32_3 0x000ffdffU 13 | #define DSFMT_MSK32_4 0xfc90fffdU 14 | #define DSFMT_FIX1 UINT64_C(0x90014964b32f4329) 15 | #define DSFMT_FIX2 UINT64_C(0x3b8d12ac548a7c7a) 16 | #define DSFMT_PCV1 UINT64_C(0x3d84e1ac0dc82880) 17 | #define DSFMT_PCV2 UINT64_C(0x0000000000000001) 18 | #define DSFMT_IDSTR "dSFMT2-19937:117-19:ffafffffffb3f-ffdfffc90fffd" 19 | 20 | 21 | /* PARAMETERS FOR ALTIVEC */ 22 | #if defined(__APPLE__) /* For OSX */ 23 | #define ALTI_SL1 (vector unsigned char)(3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3) 24 | #define ALTI_SL1_PERM \ 25 | (vector unsigned char)(2,3,4,5,6,7,30,30,10,11,12,13,14,15,0,1) 26 | #define ALTI_SL1_MSK \ 27 | (vector unsigned int)(0xffffffffU,0xfff80000U,0xffffffffU,0xfff80000U) 28 | #define ALTI_MSK (vector unsigned int)(DSFMT_MSK32_1, \ 29 | DSFMT_MSK32_2, DSFMT_MSK32_3, DSFMT_MSK32_4) 30 | #else /* For OTHER OSs(Linux?) */ 31 | #define ALTI_SL1 {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3} 32 | #define ALTI_SL1_PERM \ 33 | {2,3,4,5,6,7,30,30,10,11,12,13,14,15,0,1} 34 | #define ALTI_SL1_MSK \ 35 | {0xffffffffU,0xfff80000U,0xffffffffU,0xfff80000U} 36 | #define ALTI_MSK \ 37 | {DSFMT_MSK32_1, DSFMT_MSK32_2, DSFMT_MSK32_3, DSFMT_MSK32_4} 38 | #endif 39 | 40 | #endif /* DSFMT_PARAMS19937_H */ 41 | -------------------------------------------------------------------------------- /randomgen/src/dsfmt/dSFMT-test-gen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cl dSFMT-test-gen.c dSFMT.c dSFMT-jump.c -DHAVE_SSE2 -DDSFMT_MEXP=19937 /O2 3 | * 4 | * gcc dSFMT-test-gen.c dSFMT.c dSFMT-jump.c -DHAVE_SSE2 -DDSFMT_MEXP=19937 -o dSFMT 5 | */ 6 | 7 | #include 8 | #include 9 | #include "dsfmt.h" 10 | #include "dsfmt-test-data-seed.h" 11 | 12 | 13 | int main(void) { 14 | int i; 15 | double d; 16 | uint64_t *temp; 17 | uint32_t seed = 0UL; 18 | dsfmt_t state; 19 | dsfmt_init_by_array(&state, seed_seq_0, 2 * DSFMT_N64); 20 | double out[1000]; 21 | dsfmt_fill_array_close1_open2(&state, out, 1000); 22 | 23 | FILE *fp; 24 | fp = fopen("dSFMT-testset-1.csv", "w"); 25 | if (fp == NULL) { 26 | printf("Couldn't open file\n"); 27 | return -1; 28 | } 29 | fprintf(fp, "seed, %" PRIu32 "\n", seed); 30 | for (i = 0; i < 1000; i++) { 31 | d = out[i]; 32 | temp = (uint64_t *)&d; 33 | fprintf(fp, "%d, %" PRIu64 "\n", i, *temp); 34 | if (i==999) { 35 | printf("%d, %" PRIu64 "\n", i, *temp); 36 | } 37 | } 38 | fclose(fp); 39 | 40 | seed = 0xDEADBEAFUL; 41 | dsfmt_init_by_array(&state, seed_seq_deadbeaf, 2 * DSFMT_N64); 42 | dsfmt_fill_array_close1_open2(&state, out, 1000); 43 | fp = fopen("dSFMT-testset-2.csv", "w"); 44 | if (fp == NULL) { 45 | printf("Couldn't open file\n"); 46 | return -1; 47 | } 48 | fprintf(fp, "seed, %" PRIu32 "\n", seed); 49 | for (i = 0; i < 1000; i++) { 50 | d = out[i]; 51 | temp = (uint64_t *)&d; 52 | fprintf(fp, "%d, %" PRIu64 "\n", i, *temp); 53 | if (i==999) { 54 | printf("%d, %" PRIu64 "\n", i, *temp); 55 | } 56 | } 57 | fclose(fp); 58 | } 59 | -------------------------------------------------------------------------------- /randomgen/src/efiix64/efiix64-test-gen.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Extact PractRand-pre0.95 and then compile using 4 | 5 | g++ -std=c++14 efiix64-test-gen.cpp src/*.cpp src/RNGs/*.cpp 6 | src/RNGs/other/*.cpp -O3 -Iinclude -pthread -o efiix64-test-gen 7 | 8 | then 9 | 10 | ./efiix64-test-gen 11 | */ 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include "include/PractRand.h" 19 | #include "include/PractRand/RNGs/efiix64x48.h" 20 | #include 21 | 22 | #define N 1000 23 | 24 | int main() { 25 | std::ofstream ofile1, ofile2; 26 | uint64_t last; 27 | 28 | PractRand::RNGs::Polymorphic::efiix64x48 rng = 29 | PractRand::RNGs::Polymorphic::efiix64x48(0ULL); 30 | /* First 4 values from SeedSequence(0)*/ 31 | rng.seed(15793235383387715774ULL, 12390638538380655177ULL, 32 | 2361836109651742017ULL, 3188717715514472916ULL); 33 | ofile1.open("efiix64-testset-1.csv"); 34 | ofile1 << "seed, 0x" << 0 << std::endl; 35 | for (int i = 0; i < N; i++) { 36 | last = rng.raw64(); 37 | ofile1 << i << ", 0x" << std::hex << last << std::endl; 38 | }; 39 | ofile1.close(); 40 | std::cout << std::dec << N - 1 << ", 0x" << std::hex << last << "\n"; 41 | 42 | /* First 4 values from SeedSequence(0xDEADBEEF)*/ 43 | rng.seed(10671498545779160169ULL, 17039977206943430958ULL, 44 | 8098813118336512226ULL, 451580776527170015ULL); 45 | ofile2.open("efiix64-testset-2.csv"); 46 | ofile2 << "seed, 0x" << std::hex << 0xDEADBEEF << std::endl; 47 | for (int i = 0; i < N; i++) { 48 | last = rng.raw64(); 49 | ofile2 << i << ", 0x" << std::hex << last << std::endl; 50 | }; 51 | ofile2.close(); 52 | std::cout << std::dec << N - 1 << ", 0x" << std::hex << last << "\n"; 53 | } 54 | -------------------------------------------------------------------------------- /randomgen/src/entropy/LICENSE.md: -------------------------------------------------------------------------------- 1 | # ENTROPY 2 | 3 | _Parts of this module were derived from PCG_ 4 | 5 | 6 | PCG Random Number Generation for C. 7 | 8 | Copyright 2014 Melissa O'Neill 9 | 10 | Licensed under the Apache License, Version 2.0 (the "License"); 11 | you may not use this file except in compliance with the License. 12 | You may obtain a copy of the License at 13 | 14 | https://www.apache.org/licenses/LICENSE-2.0 15 | 16 | Unless required by applicable law or agreed to in writing, software 17 | distributed under the License is distributed on an "AS IS" BASIS, 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | See the License for the specific language governing permissions and 20 | limitations under the License. 21 | 22 | For additional information about the PCG random number generation scheme, 23 | including its license and other licensing options, visit 24 | 25 | https://www.pcg-random.org 26 | -------------------------------------------------------------------------------- /randomgen/src/entropy/entropy.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__ENTROPY_H_ 2 | #define _RANDOMDGEN__ENTROPY_H_ 3 | /* 4 | * PCG Random Number Generation for C. 5 | * 6 | * Copyright 2014 Melissa O'Neill 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * https://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | * For additional information about the PCG random number generation scheme, 21 | * including its license and other licensing options, visit 22 | * 23 | * https://www.pcg-random.org 24 | */ 25 | 26 | #include "../common/randomgen_config.h" 27 | 28 | extern void entropy_fill(void *dest, size_t size); 29 | 30 | extern bool entropy_getbytes(void *dest, size_t size); 31 | 32 | extern bool entropy_fallback_getbytes(void *dest, size_t size); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /randomgen/src/hc-128/hc-128.c: -------------------------------------------------------------------------------- 1 | #include "hc-128.h" 2 | 3 | uint32_t pack_littleendian(const uint8_t *v) 4 | { 5 | return *((uint32_t *)v); 6 | } 7 | 8 | void unpack_littleendian(uint32_t value, uint8_t *v) 9 | { 10 | *((uint32_t *)v) = value; 11 | } 12 | 13 | /* Init Only */ 14 | static uint32_t f1(uint32_t x) { return rotl(x, 25) ^ rotl(x, 14) ^ (x >> 3); } 15 | static uint32_t f2(uint32_t x) { return rotl(x, 15) ^ rotl(x, 13) ^ (x >> 10); } 16 | 17 | void hc128_init(hc128_state_t *state, const uint8_t *key, const uint8_t *iv) 18 | { 19 | unsigned int i; 20 | uint32_t w[1280]; 21 | uint32_t *p, *q; 22 | for (i = 0; i < 4; ++i) 23 | { 24 | w[i] = w[i + 4] = pack_littleendian(key + 4 * i); 25 | w[i + 8] = w[i + 12] = pack_littleendian(iv + 4 * i); 26 | } 27 | 28 | for (i = 16; i < 1280; ++i) 29 | { 30 | w[i] = f2(w[i - 2]) + w[i - 7] + f1(w[i - 15]) + w[i - 16] + i; 31 | } 32 | 33 | p = state->p; 34 | q = state->q; 35 | 36 | for (i = 0; i < 512; ++i) 37 | { 38 | p[i] = w[i + 256]; 39 | q[i] = w[i + 768]; 40 | } 41 | 42 | for (i = 0; i < 512; ++i) 43 | p[i] = round_expression_pq(p, q, i); 44 | 45 | for (i = 0; i < 512; ++i) 46 | q[i] = round_expression_qp(q, p, i); 47 | 48 | state->hc_idx = 0; 49 | } 50 | 51 | void hc128_seed(hc128_state_t *state, uint32_t *seed) 52 | { 53 | hc128_init(state, (uint8_t *)&seed[0], (uint8_t *)&seed[4]); 54 | } 55 | 56 | extern INLINE uint32_t hc128_next32(hc128_state_t *state); 57 | extern INLINE uint64_t hc128_next64(hc128_state_t *state); 58 | extern INLINE double hc128_next_double(hc128_state_t *state); 59 | -------------------------------------------------------------------------------- /randomgen/src/hc-128/hc-128.orig.h: -------------------------------------------------------------------------------- 1 | /* Author: Lucas Clemente Vella 2 | * Source code placed into public domain. */ 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | typedef struct 9 | { 10 | uint32_t p[512]; 11 | uint32_t q[512]; 12 | uint16_t i; 13 | } hc128_state; 14 | 15 | /** Initialize HC-128 state with key and IV. 16 | * 17 | * Contrary to the other implemented algorithms, the key and IV are taken 18 | * in a single function to initialize the state. This approach was chosen 19 | * here because of the nature of the algorithm, that keeps no intermediate 20 | * state between the key setting and the IV setting. 21 | * 22 | * Notice: an IV should never be reused. 23 | * 24 | * @param state The uninitialized state, it will be ready to 25 | * encryption/decryption afterwards. 26 | * @param key 16 bytes buffer containing the 128-bit key. The buffer must 27 | * be aligned to at least 4 bytes (depending on the platform it may or may 28 | * not work with unaligned memory). 29 | * @param iv 16 bytes buffer containing the IV. 30 | */ 31 | void hc128_init(hc128_state *state, const uint8_t *key, const uint8_t *iv); 32 | 33 | /** Performs one round of the algorithm. 34 | * 35 | * @param state The algorithm state. 36 | * @param stream A 4 byte buffer where the generated stream will be stored. 37 | * Must be aligned. 38 | */ 39 | void hc128_extract(hc128_state *state, uint8_t *stream); 40 | -------------------------------------------------------------------------------- /randomgen/src/hc-128/util.orig.c: -------------------------------------------------------------------------------- 1 | /* Author: Lucas Clemente Vella 2 | * Source code placed into public domain. */ 3 | 4 | #include "util.orig.h" 5 | 6 | uint32_t 7 | rotl(uint32_t x, unsigned int n) 8 | { 9 | return (x << n) | (x >> (32-n)); 10 | } 11 | 12 | uint32_t 13 | pack_littleendian(const uint8_t *v) 14 | { 15 | #ifdef LITTLE_ENDIAN 16 | return *((uint32_t*)v); 17 | #else 18 | #error "Only use on LE" 19 | return (uint32_t)v[3] << 24 20 | | (uint32_t)v[2] << 16 21 | | (uint32_t)v[1] << 8 22 | | (uint32_t)v[0]; 23 | #endif 24 | } 25 | 26 | void 27 | unpack_littleendian(uint32_t value, uint8_t *v) 28 | { 29 | #ifdef LITTLE_ENDIAN 30 | *((uint32_t*)v) = value; 31 | #else 32 | #error "Only use on LE" 33 | int i; 34 | for(i = 0; i < 4; ++i) 35 | v[i] = value >> (i * 8); 36 | #endif 37 | } 38 | 39 | size_t 40 | min(size_t a, size_t b) 41 | { 42 | return (a < b) ? a : b; 43 | } 44 | 45 | int 46 | is_aligned(const void *ptr) 47 | { 48 | return ((unsigned)ptr & 3u) == 0; /* Multiple of 4 */ 49 | } 50 | -------------------------------------------------------------------------------- /randomgen/src/hc-128/util.orig.h: -------------------------------------------------------------------------------- 1 | /* Author: Lucas Clemente Vella 2 | * Source code placed into public domain. */ 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #ifdef UNALIGNED_ACCESS_ALLOWED 10 | #define UNALIGNED_ACCESS 1 11 | #else 12 | #define UNALIGNED_ACCESS 0 13 | #endif 14 | 15 | uint32_t rotl(uint32_t x, unsigned int n); 16 | 17 | uint32_t pack_littleendian(const uint8_t *v); 18 | void unpack_littleendian(uint32_t value, uint8_t *v); 19 | 20 | size_t min(size_t a, size_t b); 21 | 22 | int is_aligned(const void *ptr); 23 | -------------------------------------------------------------------------------- /randomgen/src/jsf/jsf.c: -------------------------------------------------------------------------------- 1 | #include "jsf.h" 2 | 3 | extern INLINE uint64_t jsf64_next64(jsf_state_t *state); 4 | extern INLINE uint32_t jsf64_next32(jsf_state_t *state); 5 | extern INLINE double jsf64_next_double(jsf_state_t *state); 6 | extern INLINE uint64_t jsf32_next64(jsf_state_t *state); 7 | extern INLINE uint32_t jsf32_next32(jsf_state_t *state); 8 | extern INLINE double jsf32_next_double(jsf_state_t *state); 9 | 10 | void jsf64_seed(jsf_state_t *state, uint64_t *seed, int size) { 11 | int i; 12 | state->a.u64 = 0xf1ea5eed; 13 | state->b.u64 = seed[0]; 14 | state->c.u64 = seed[0]; 15 | state->d.u64 = seed[0]; 16 | if (size > 1) state->c.u64 = seed[1]; 17 | if (size > 2) state->d.u64 = seed[2]; 18 | for (i = 0; i < 20; ++i) { 19 | next64(state); 20 | } 21 | } 22 | 23 | void jsf32_seed(jsf_state_t *state, uint32_t* seed, int size) { 24 | int i; 25 | state->a.u32 = 0xf1ea5eed; 26 | state->b.u32 = seed[0]; 27 | state->c.u32 = seed[0]; 28 | state->d.u32 = seed[0]; 29 | if (size > 1) state->c.u32 = seed[1]; 30 | if (size > 2) state->d.u32 = seed[2]; 31 | for (i = 0; i < 20; ++i) { 32 | next32(state); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /randomgen/src/legacy/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2005-2017, NumPy Developers. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of the NumPy Developers nor the names of any 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /randomgen/src/lxm/lxm.c: -------------------------------------------------------------------------------- 1 | #include "lxm.h" 2 | 3 | extern inline void lcg(lxm_state_t *state); 4 | 5 | extern inline uint64_t lxm_next64(lxm_state_t *state); 6 | 7 | void lcg_jump(lxm_state_t *state) { 8 | uint64_t acc_mult = 1u; 9 | uint64_t acc_plus = 0u; 10 | uint64_t cur_plus = state->b; 11 | uint64_t cur_mult = LCG_MULT; 12 | /* 2^128 has bit 1 in location 128, and 0 else where */ 13 | for (int i=0; i < 129; i++){ 14 | if (i == 128) { 15 | acc_mult *= cur_mult; 16 | acc_plus = acc_plus * cur_mult + cur_plus; 17 | } 18 | cur_plus = (cur_mult + 1) * cur_plus; 19 | cur_mult *= cur_mult; 20 | } 21 | state->lcg_state = acc_mult * state->lcg_state + acc_plus; 22 | } 23 | 24 | void xorshift_jump(lxm_state_t *state) 25 | { 26 | static const uint64_t JUMP[] = {0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 27 | 0x39abdc4529b1661c}; 28 | 29 | uint64_t s0 = 0; 30 | uint64_t s1 = 0; 31 | uint64_t s2 = 0; 32 | uint64_t s3 = 0; 33 | for (int i = 0; i < (int)(sizeof(JUMP) / sizeof(*JUMP)); i++) 34 | for (int b = 0; b < 64; b++) 35 | { 36 | if (JUMP[i] & UINT64_C(1) << b) 37 | { 38 | s0 ^= state->x[0]; 39 | s1 ^= state->x[1]; 40 | s2 ^= state->x[2]; 41 | s3 ^= state->x[3]; 42 | } 43 | xorshift(state); 44 | } 45 | 46 | state->x[0] = s0; 47 | state->x[1] = s1; 48 | state->x[2] = s2; 49 | state->x[3] = s3; 50 | } 51 | 52 | void lxm_jump(lxm_state_t *state) 53 | { 54 | 55 | /* 56 | * lcg jump is a no-op since we are using a multiplier 57 | * the full cycle 58 | * 59 | * lcg_jump(state); 60 | */ 61 | xorshift_jump(state); 62 | } 63 | -------------------------------------------------------------------------------- /randomgen/src/mt19937/mt19937-benchmark.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cl mt19937-benchmark.c mt19937.c /Ox 3 | * Measure-Command { .\mt19937-benchmark.exe } 4 | * 5 | * gcc mt19937-benchmark.c mt19937.c -O3 -o mt19937-benchmark 6 | * time ./mt19937-benchmark 7 | */ 8 | #include "mt19937.h" 9 | #include 10 | #include 11 | #include 12 | 13 | #define Q 1000000000 14 | 15 | int main() { 16 | int i; 17 | uint32_t seed = 0x0; 18 | uint64_t sum = 0, count = 0; 19 | mt19937_state state; 20 | mt19937_seed(&state, seed); 21 | clock_t begin = clock(); 22 | for (i = 0; i < Q; i++) { 23 | sum += mt19937_next64(&state); 24 | count++; 25 | } 26 | clock_t end = clock(); 27 | double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 28 | printf("0x%" PRIx64 "\ncount: %" PRIu64 "\n", sum, count); 29 | printf("%" PRIu64 " randoms per second\n", 30 | (uint64_t)(Q / time_spent) / 1000000 * 1000000); 31 | } 32 | -------------------------------------------------------------------------------- /randomgen/src/mt19937/mt19937-jump.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "mt19937.h" 3 | #include 4 | 5 | /* parameters for computing Jump */ 6 | #define W_SIZE 32 /* size of unsigned long */ 7 | #define MEXP 19937 8 | #define P_SIZE ((MEXP / W_SIZE) + 1) 9 | #define LSB 0x00000001UL 10 | #define QQ 7 11 | #define LL 128 /* LL = 2^(QQ) */ 12 | 13 | void mt19937_jump_state(mt19937_state_t *state, const char *jump_str); 14 | 15 | void set_coef(unsigned long *pf, unsigned int deg, unsigned long v); -------------------------------------------------------------------------------- /randomgen/src/mt19937/mt19937-test-data-gen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Generate testing csv files 3 | * 4 | * cl mt19937-test-data-gen.c randomkit.c -IC:\anaconda\envs\randomgen\Lib\site-packages\numpy\_core\include -IC:\anaconda\envs\randomgen\include Advapi32.lib Kernel32.lib C:\anaconda\envs\randomgen\libs\python312.lib -DRK_NO_WINCRYPT=1 5 | * 6 | */ 7 | #include "randomkit.h" 8 | #include 9 | #include 10 | #include "mt119937-test-data-seed.h" 11 | #define N 1000 12 | 13 | int main() { 14 | uint64_t sum = 0; 15 | uint32_t seed = 0xDEADBEAF; 16 | int i; 17 | rk_state state; 18 | uint64_t store[N]; 19 | rk_init_by_array(&state, (uint32_t *)&seed_seq_deadbeaf, 624); 20 | for (i = 0; i < N; i++) { 21 | store[i] = (uint64_t)rk_random(&state); 22 | } 23 | 24 | FILE *fp; 25 | fp = fopen("mt19937-testset-1.csv", "w"); 26 | if (fp == NULL) { 27 | printf("Couldn't open file\n"); 28 | return -1; 29 | } 30 | fprintf(fp, "seed, 0x%" PRIx32 "\n", seed); 31 | for (i = 0; i < N; i++) { 32 | fprintf(fp, "%d, 0x%" PRIx64 "\n", i, store[i]); 33 | if (i == 999) { 34 | printf("%d, 0x%" PRIx64 "\n", i, store[i]); 35 | } 36 | } 37 | fclose(fp); 38 | 39 | seed = 0; 40 | rk_init_by_array(&state, (uint32_t *)&seed_seq_0, 624); 41 | for (i = 0; i < N; i++) { 42 | store[i] = (uint64_t)rk_random(&state); 43 | } 44 | fp = fopen("mt19937-testset-2.csv", "w"); 45 | if (fp == NULL) { 46 | printf("Couldn't open file\n"); 47 | return -1; 48 | } 49 | fprintf(fp, "seed, 0x%" PRIx32 "\n", seed); 50 | for (i = 0; i < N; i++) { 51 | fprintf(fp, "%d, 0x%" PRIx64 "\n", i, store[i]); 52 | if (i == 999) { 53 | printf("%d, 0x%" PRIx64 "\n", i, store[i]); 54 | } 55 | } 56 | fclose(fp); 57 | } 58 | -------------------------------------------------------------------------------- /randomgen/src/mt19937/mt19937.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../common/randomgen_config.h" 5 | 6 | #define RK_STATE_LEN 624 7 | 8 | #define N 624 9 | #define M 397 10 | #define MATRIX_A 0x9908b0dfUL 11 | #define UPPER_MASK 0x80000000UL 12 | #define LOWER_MASK 0x7fffffffUL 13 | 14 | typedef struct MT19937_STATE_T { 15 | uint32_t key[RK_STATE_LEN]; 16 | int pos; 17 | } mt19937_state_t; 18 | 19 | extern void mt19937_seed(mt19937_state_t *state, uint32_t seed); 20 | 21 | extern void mt19937_gen(mt19937_state_t *state); 22 | 23 | /* Slightly optimized reference implementation of the Mersenne Twister */ 24 | static INLINE uint32_t mt19937_next(mt19937_state_t *state) { 25 | uint32_t y; 26 | 27 | if (state->pos == RK_STATE_LEN) { 28 | // Move to function to help inlining 29 | mt19937_gen(state); 30 | } 31 | y = state->key[state->pos++]; 32 | 33 | /* Tempering */ 34 | y ^= (y >> 11); 35 | y ^= (y << 7) & 0x9d2c5680UL; 36 | y ^= (y << 15) & 0xefc60000UL; 37 | y ^= (y >> 18); 38 | 39 | return y; 40 | } 41 | 42 | extern void mt19937_init_by_array(mt19937_state_t *state, uint32_t *init_key, 43 | int key_length); 44 | 45 | static INLINE uint64_t mt19937_next64(mt19937_state_t *state) { 46 | return (uint64_t)mt19937_next(state) << 32 | mt19937_next(state); 47 | } 48 | 49 | static INLINE uint32_t mt19937_next32(mt19937_state_t *state) { 50 | return mt19937_next(state); 51 | } 52 | 53 | static INLINE double mt19937_next_double(mt19937_state_t *state) { 54 | int32_t a = mt19937_next(state) >> 5, b = mt19937_next(state) >> 6; 55 | return (a * 67108864.0 + b) / 9007199254740992.0; 56 | } 57 | 58 | void mt19937_jump(mt19937_state_t *state); 59 | void mt19937_jump_default(mt19937_state_t *state); 60 | void mt19937_jump_n(mt19937_state_t *state, int count); 61 | -------------------------------------------------------------------------------- /randomgen/src/mt64/mt64-test-data-gen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Generate testing csv files 3 | * 4 | * cl mt64-test-data-gen.c mt64.orig.c /Ox 5 | * mt19937-64-test-data-gen.exe 6 | * 7 | * gcc mt64-test-data-gen.c mt64-64.orig.c -o mt64-test-data-gen 8 | * ./mt19937-64-test-data-gen 9 | * 10 | */ 11 | 12 | #include "mt64-test-data-seed.h" 13 | #include "mt64.orig.h" 14 | #include 15 | #include 16 | 17 | #define N 1000 18 | 19 | int main() { 20 | uint64_t sum = 0; 21 | uint64_t state, seed = 0xDEADBEAF; 22 | state = seed; 23 | int i; 24 | uint64_t store[N]; 25 | init_by_array64(&seed_seq_deadbeaf, 312); 26 | 27 | for (i = 0; i < N; i++) { 28 | store[i] = genrand64_int64(); 29 | } 30 | 31 | FILE *fp; 32 | fp = fopen("mt64-testset-1.csv", "w"); 33 | if (fp == NULL) { 34 | printf("Couldn't open file\n"); 35 | return -1; 36 | } 37 | fprintf(fp, "seed, 0x%" PRIx64 "\n", seed); 38 | for (i = 0; i < N; i++) { 39 | fprintf(fp, "%d, 0x%" PRIx64 "\n", i, store[i]); 40 | if (i == 999) { 41 | printf("%d, 0x%" PRIx64 "\n", i, store[i]); 42 | } 43 | } 44 | fclose(fp); 45 | 46 | seed = state = 0; 47 | init_by_array64(&seed_seq_0, 312); 48 | for (i = 0; i < N; i++) { 49 | store[i] = genrand64_int64(); 50 | } 51 | fp = fopen("mt64-testset-2.csv", "w"); 52 | if (fp == NULL) { 53 | printf("Couldn't open file\n"); 54 | return -1; 55 | } 56 | fprintf(fp, "seed, 0x%" PRIx64 "\n", seed); 57 | for (i = 0; i < N; i++) { 58 | fprintf(fp, "%d, 0x%" PRIx64 "\n", i, store[i]); 59 | if (i == 999) { 60 | printf("%d, 0x%" PRIx64 "\n", i, store[i]); 61 | } 62 | } 63 | fclose(fp); 64 | } 65 | -------------------------------------------------------------------------------- /randomgen/src/pcg32/LICENSE.md: -------------------------------------------------------------------------------- 1 | # PCG32 2 | 3 | PCG Random Number Generation for C. 4 | 5 | Copyright 2014 Melissa O'Neill 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | https://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | For additional information about the PCG random number generation scheme, 20 | including its license and other licensing options, visit 21 | 22 | https://www.pcg-random.org 23 | -------------------------------------------------------------------------------- /randomgen/src/pcg32/pcg32.c: -------------------------------------------------------------------------------- 1 | #include "pcg32.h" 2 | 3 | extern inline uint64_t pcg32_next64(pcg32_state_t *state); 4 | extern inline uint32_t pcg32_next32(pcg32_state_t *state); 5 | extern inline double pcg32_next_double(pcg32_state_t *state); 6 | 7 | uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, uint64_t cur_mult, 8 | uint64_t cur_plus) { 9 | uint64_t acc_mult, acc_plus; 10 | acc_mult = 1u; 11 | acc_plus = 0u; 12 | while (delta > 0) { 13 | if (delta & 1) { 14 | acc_mult *= cur_mult; 15 | acc_plus = acc_plus * cur_mult + cur_plus; 16 | } 17 | cur_plus = (cur_mult + 1) * cur_plus; 18 | cur_mult *= cur_mult; 19 | delta /= 2; 20 | } 21 | return acc_mult * state + acc_plus; 22 | } 23 | 24 | extern void pcg32_advance_state(pcg32_state_t *state, uint64_t step) { 25 | pcg32_advance_r(&state->pcg_state, step); 26 | } 27 | 28 | extern void pcg32_set_seed(pcg32_state_t *state, uint64_t seed, uint64_t inc) { 29 | pcg32_srandom_r(&state->pcg_state, seed, inc); 30 | } 31 | -------------------------------------------------------------------------------- /randomgen/src/pcg64/LICENSE.md: -------------------------------------------------------------------------------- 1 | # PCG64 2 | 3 | PCG Random Number Generation for C. 4 | 5 | Copyright 2014 Melissa O'Neill 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | https://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | For additional information about the PCG random number generation scheme, 20 | including its license and other licensing options, visit 21 | 22 | https://www.pcg-random.org 23 | -------------------------------------------------------------------------------- /randomgen/src/pcg64/lcg128mix.c: -------------------------------------------------------------------------------- 1 | #include "lcg128mix.h" 2 | 3 | extern INLINE uint64_t lcg128mix_next64(lcg128mix_state_t *state); 4 | extern INLINE uint32_t lcg128mix_next32(lcg128mix_state_t *state); 5 | 6 | extern void lcg128mix_set_state(lcg128mix_random_t *rng, uint64_t state[], uint64_t inc[], 7 | uint64_t multiplier[]) { 8 | rng->state = PCG_128BIT_CONSTANT(state[0], state[1]); 9 | rng->inc = PCG_128BIT_CONSTANT(inc[0], inc[1]); 10 | rng->multiplier = PCG_128BIT_CONSTANT(multiplier[0], multiplier[1]); 11 | } 12 | 13 | extern void lcg128mix_get_state(lcg128mix_random_t *rng, uint64_t state[], uint64_t inc[], 14 | uint64_t multiplier[]) { 15 | state[0] = PCG_HIGH(rng->state); 16 | state[1] = PCG_LOW(rng->state); 17 | inc[0] = PCG_HIGH(rng->inc); 18 | inc[1] = PCG_LOW(rng->inc); 19 | multiplier[0] = PCG_HIGH(rng->multiplier); 20 | multiplier[1] = PCG_LOW(rng->multiplier); 21 | } 22 | 23 | extern void lcg128mix_seed(lcg128mix_random_t *rng, uint64_t state[], uint64_t inc[], 24 | uint64_t multiplier[]) { 25 | rng->multiplier = PCG_128BIT_CONSTANT(multiplier[0], multiplier[1]); 26 | pcg128_t initstate, initinc; 27 | initstate = PCG_128BIT_CONSTANT(state[0], state[1]); 28 | initinc = PCG_128BIT_CONSTANT(inc[0], inc[1]); 29 | lcg128mix_initialize(rng, initstate, initinc); 30 | } 31 | 32 | static void lcg128mix_advance_r(lcg128mix_random_t *rng, pcg128_t delta) { 33 | rng->state = pcg_advance_lcg_128(rng->state, delta, rng->multiplier, rng->inc); 34 | } 35 | 36 | extern void lcg128mix_advance(lcg128mix_state_t *rng, uint64_t step[]) { 37 | pcg128_t delta = PCG_128BIT_CONSTANT(step[0], step[1]); 38 | lcg128mix_advance_r(rng->pcg_state, delta); 39 | } 40 | -------------------------------------------------------------------------------- /randomgen/src/pcg64/pcg64-benchmark.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cl pcg64-benchmark.c pcg64.c ../splitmix64/splitmix64.c /Ox 3 | * Measure-Command { .\xoroshiro128-benchmark.exe } 4 | * 5 | * gcc pcg64-benchmark.c pcg64.c ../splitmix64/splitmix64.c -O3 -o 6 | * pcg64-benchmark 7 | * time ./pcg64-benchmark 8 | */ 9 | #include "../splitmix64/splitmix64.h" 10 | #include "pcg64.h" 11 | #include 12 | #include 13 | #include 14 | 15 | #define N 1000000000 16 | 17 | int main() { 18 | pcg64_random_t rng; 19 | uint64_t sum = 0, count = 0; 20 | uint64_t seed = 0xDEADBEAF; 21 | int i; 22 | #if __SIZEOF_INT128__ && !defined(PCG_FORCE_EMULATED_128BIT_MATH) 23 | rng.state = (__uint128_t)splitmix64_next(&seed) << 64; 24 | rng.state |= splitmix64_next(&seed); 25 | rng.inc = (__uint128_t)1; 26 | #else 27 | rng.state.high = splitmix64_next(&seed); 28 | rng.state.low = splitmix64_next(&seed); 29 | rng.inc.high = 0; 30 | rng.inc.low = 1; 31 | #endif 32 | clock_t begin = clock(); 33 | for (i = 0; i < N; i++) { 34 | sum += pcg64_random_r(&rng); 35 | count++; 36 | } 37 | clock_t end = clock(); 38 | double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 39 | printf("0x%" PRIx64 "\ncount: %" PRIu64 "\n", sum, count); 40 | printf("%" PRIu64 " randoms per second\n", (uint64_t)(N / time_spent) / 1000000 * 1000000); 41 | } 42 | -------------------------------------------------------------------------------- /randomgen/src/pcg64/pcg64-common.c: -------------------------------------------------------------------------------- 1 | #include "pcg64-common.h" 2 | 3 | #if !defined(PCG_EMULATED_128BIT_MATH) || !(PCG_EMULATED_128BIT_MATH) 4 | 5 | pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, pcg128_t cur_mult, pcg128_t cur_plus) { 6 | pcg128_t acc_mult = 1u; 7 | pcg128_t acc_plus = 0u; 8 | while (delta > 0) { 9 | if (delta & 1) { 10 | acc_mult *= cur_mult; 11 | acc_plus = acc_plus * cur_mult + cur_plus; 12 | } 13 | cur_plus = (cur_mult + 1) * cur_plus; 14 | cur_mult *= cur_mult; 15 | delta /= 2; 16 | } 17 | return acc_mult * state + acc_plus; 18 | } 19 | 20 | #else 21 | 22 | pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, pcg128_t cur_mult, pcg128_t cur_plus) { 23 | pcg128_t acc_mult = PCG_128BIT_CONSTANT(0u, 1u); 24 | pcg128_t acc_plus = PCG_128BIT_CONSTANT(0u, 0u); 25 | while ((delta.high > 0) || (delta.low > 0)) { 26 | if (delta.low & 1) { 27 | acc_mult = pcg128_mult(acc_mult, cur_mult); 28 | acc_plus = pcg128_add(pcg128_mult(acc_plus, cur_mult), cur_plus); 29 | } 30 | cur_plus = pcg128_mult(pcg128_add(cur_mult, PCG_128BIT_CONSTANT(0u, 1u)), cur_plus); 31 | cur_mult = pcg128_mult(cur_mult, cur_mult); 32 | delta.low = (delta.low >> 1) | (delta.high << 63); 33 | delta.high >>= 1; 34 | } 35 | return pcg128_add(pcg128_mult(acc_mult, state), acc_plus); 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /randomgen/src/pcg64/pcg64.orig.c: -------------------------------------------------------------------------------- 1 | #include "pcg64.orig.h" 2 | 3 | extern inline void pcg_setseq_128_srandom_r(pcg64_random_t *rng, 4 | pcg128_t initstate, 5 | pcg128_t initseq); 6 | 7 | extern uint64_t pcg_rotr_64(uint64_t value, unsigned int rot); 8 | extern inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state); 9 | extern void pcg_setseq_128_step_r(struct pcg_state_setseq_128 *rng); 10 | extern uint64_t 11 | pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128 *rng); 12 | -------------------------------------------------------------------------------- /randomgen/src/philox/LICENSE.md: -------------------------------------------------------------------------------- 1 | # THREEFRY 2 | 3 | Copyright 2010-2012, D. E. Shaw Research. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are 8 | met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions, and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions, and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | 17 | * Neither the name of D. E. Shaw Research nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /randomgen/src/philox/philox-benchmark.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple benchamrk command 3 | * 4 | * cl philox-benchmark.c /Ox 5 | * 6 | * gcc philox-benchmark.c -O3 -o philox-benchmark 7 | * 8 | * Requres the Random123 directory containing header files to be located in the 9 | * same directory (not included). 10 | */ 11 | #include "Random123/philox.h" 12 | #include 13 | #include 14 | #include 15 | 16 | #define N 1000000000 17 | 18 | int main() { 19 | philox4x64_ctr_t ctr = {{0, 0, 0, 0}}; 20 | philox4x64_key_t key = {{0, 0xDEADBEAF}}; 21 | philox4x64_ctr_t out; 22 | uint64_t count = 0, sum = 0; 23 | int i, j; 24 | clock_t begin = clock(); 25 | for (i = 0; i < N / 4UL; i++) { 26 | ctr.v[0]++; 27 | out = philox4x64_R(philox4x64_rounds, ctr, key); 28 | for (j = 0; j < 4; j++) { 29 | sum += out.v[j]; 30 | count++; 31 | } 32 | } 33 | clock_t end = clock(); 34 | double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 35 | printf("0x%" PRIx64 "\ncount: %" PRIu64 "\n", sum, count); 36 | printf("%" PRIu64 " randoms per second\n", (uint64_t)((double)N / time_spent)); 37 | printf("%0.3f ms to produce 1,000,000 draws \n", 1000*1000000.0 * (time_spent/(double)N)); 38 | } 39 | -------------------------------------------------------------------------------- /randomgen/src/rdrand/rdrand.c: -------------------------------------------------------------------------------- 1 | #include "rdrand.h" 2 | #include "../common/cpu_features.h" 3 | 4 | #define RANDOMGEN_USE_RDRAND 30 5 | 6 | extern INLINE int rdrand_fill_buffer(rdrand_state *state); 7 | extern INLINE int rdrand_next64(rdrand_state *state, uint64_t *val); 8 | 9 | int rdrand_capable(void) { 10 | #if defined(__RDRND__) && __RDRND__ 11 | int flags[32]; 12 | feature_flags(flags, RANDOMGEN_ECX); 13 | return flags[RANDOMGEN_USE_RDRAND]; 14 | #else 15 | return 0; 16 | #endif 17 | } 18 | -------------------------------------------------------------------------------- /randomgen/src/romu/romu.c: -------------------------------------------------------------------------------- 1 | #include "romu.h" 2 | 3 | extern INLINE uint64_t romuquad_next64(romu_state_t *state); 4 | extern INLINE uint64_t romutrio_next64(romu_state_t *state); 5 | extern INLINE uint32_t romuquad_next32(romu_state_t *state); 6 | extern INLINE uint32_t romutrio_next32(romu_state_t *state); 7 | 8 | void romu_seed(romu_state_t *state, uint64_t w, uint64_t x, uint64_t y, uint64_t z, int quad) { 9 | state->w = w; 10 | state->x = x; 11 | state->y = y; 12 | state->z = z; 13 | /* Recommended in the paper */ 14 | for (int i = 0; i < 10; i++) { 15 | if (quad != 0) { 16 | romuquad_next64(state); 17 | } else { 18 | romutrio_next64(state); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /randomgen/src/sfc/sfc.c: -------------------------------------------------------------------------------- 1 | #include "sfc.h" 2 | 3 | extern INLINE uint64_t sfc_next64(sfc_state_t *state); 4 | extern INLINE uint32_t sfc_next32(sfc_state_t *state); 5 | 6 | void sfc_seed(sfc_state_t *state, uint64_t *seed, uint64_t w, uint64_t k){ 7 | state->a = seed[0]; 8 | state->b = seed[1]; 9 | state->c = seed[2]; 10 | state->w = w; 11 | state->k = k; 12 | for (int i=0; i<12; i++) { 13 | next64(state); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /randomgen/src/sfmt/sfmt-jump.h: -------------------------------------------------------------------------------- 1 | #ifndef SFMT_JUMP_H 2 | #define SFMT_JUMP_H 3 | /** 4 | * @file SFMT-jump.h 5 | * 6 | * @brief jump header file. 7 | * 8 | * @author Mutsuo Saito (Hiroshima University) 9 | * @author Makoto Matsumoto (The University of Tokyo) 10 | * 11 | * Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, 12 | * Hiroshima University and The University of Tokyo. 13 | * All rights reserved. 14 | * 15 | * The 3-clause BSD License is applied to this software, see 16 | * LICENSE.txt 17 | */ 18 | #if defined(__cplusplus) 19 | extern "C" { 20 | #endif 21 | 22 | #include "sfmt.h" 23 | void SFMT_jump(sfmt_t *sfmt, const char *jump_str); 24 | 25 | #if defined(__cplusplus) 26 | } 27 | #endif 28 | #endif 29 | -------------------------------------------------------------------------------- /randomgen/src/sfmt/sfmt-test-gen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cl sfmt-test-gen.c sfmt.c sfmt-jump.c -DHAVE_SSE2 -DSFMT_MEXP=19937 /O2 3 | * gcc sfmt-test-gen.c sfmt.c sfmt-jump.c -DHAVE_SSE2 -DSFMT_MEXP=19937 -o sfmt /O2 4 | */ 5 | #include "sfmt.h" 6 | #include "sfmt-test-data-seed.h" 7 | #include 8 | #include 9 | 10 | 11 | int main(void) { 12 | int i; 13 | uint64_t *temp; 14 | uint32_t seed = 0UL; 15 | sfmt_t state; 16 | printf("seed: %" PRIu32 "\n", SFMT_N64); 17 | sfmt_init_by_array(&state, (uint32_t *)&seed_seq_0, 2 * SFMT_N64); 18 | uint64_t out[1000]; 19 | sfmt_fill_array64(&state, out, 1000); 20 | 21 | FILE *fp; 22 | fp = fopen("sfmt-testset-1.csv", "w"); 23 | if (fp == NULL) { 24 | printf("Couldn't open file\n"); 25 | return -1; 26 | } 27 | fprintf(fp, "seed, %" PRIu32 "\n", seed); 28 | for (i = 0; i < 1000; i++) { 29 | fprintf(fp, "%d, %" PRIu64 "\n", i, out[i]); 30 | if (i == 999) { 31 | printf("%d, %" PRIu64 "\n", i, out[i]); 32 | } 33 | printf("%d, %" PRIu64 "\n", i, out[i]); 34 | } 35 | fclose(fp); 36 | 37 | seed = 0xDEADBEAFUL; 38 | sfmt_init_by_array(&state, (uint32_t *)&seed_seq_deadbeaf, 2 * SFMT_N64); 39 | sfmt_fill_array64(&state, out, 1000); 40 | fp = fopen("sfmt-testset-2.csv", "w"); 41 | if (fp == NULL) { 42 | printf("Couldn't open file\n"); 43 | return -1; 44 | } 45 | fprintf(fp, "seed, %" PRIu32 "\n", seed); 46 | for (i = 0; i < 1000; i++) { 47 | fprintf(fp, "%d, %" PRIu64 "\n", i, out[i]); 48 | if (i == 999) { 49 | printf("%d, %" PRIu64 "\n", i, out[i]); 50 | } 51 | } 52 | fclose(fp); 53 | } 54 | -------------------------------------------------------------------------------- /randomgen/src/speck-128/speck-128-common.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMGEN_SPECK_COMMON_H 2 | #define _RANDOMGEN_SPECK_COMMON_H 1 3 | 4 | #include "../common/randomgen_config.h" 5 | #include "../common/randomgen_immintrin.h" 6 | 7 | 8 | #define SPECK_UNROLL 12 9 | #define SPECK_BUFFER_SZ 8 * SPECK_UNROLL 10 | #define SPECK_MAX_ROUNDS 34 /* Only correct for 128x256 */ 11 | #define SPECK_CTR_SZ SPECK_UNROLL / 2 12 | 13 | union SPECK_T { 14 | #if defined(__SSSE3__) && __SSSE3__ 15 | __m128i m128; 16 | #endif 17 | uint64_t u64[2]; 18 | }; 19 | 20 | typedef union SPECK_T speck_t; 21 | 22 | struct SPECK_STATE_T { 23 | speck_t round_key[SPECK_MAX_ROUNDS]; 24 | speck_t ctr[SPECK_CTR_SZ]; 25 | uint8_t buffer[SPECK_BUFFER_SZ]; 26 | int rounds; 27 | 28 | int offset; 29 | int has_uint32; 30 | uint32_t uinteger; 31 | }; 32 | 33 | typedef struct SPECK_STATE_T speck_state_t; 34 | 35 | static INLINE void advance_counter(speck_state_t *state) { 36 | uint64_t low; 37 | int i; 38 | for (i = 0; i < SPECK_CTR_SZ; i++) { 39 | low = state->ctr[i].u64[0]; 40 | state->ctr[i].u64[0] += SPECK_CTR_SZ; 41 | if (state->ctr[i].u64[0] < low) 42 | state->ctr[i].u64[1]++; 43 | } 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /randomgen/src/splitmix64/LICENSE.md: -------------------------------------------------------------------------------- 1 | # SPLITMIX64 2 | 3 | Written in 2015 by Sebastiano Vigna (vigna@acm.org) 4 | 5 | To the extent possible under law, the author has dedicated all copyright 6 | and related and neighboring rights to this software to the public domain 7 | worldwide. This software is distributed without any warranty. 8 | 9 | See . -------------------------------------------------------------------------------- /randomgen/src/splitmix64/splitmix64.c: -------------------------------------------------------------------------------- 1 | /* Written in 2015 by Sebastiano Vigna (vigna@acm.org) 2 | 3 | To the extent possible under law, the author has dedicated all copyright 4 | and related and neighboring rights to this software to the public domain 5 | worldwide. This software is distributed without any warranty. 6 | 7 | See . 8 | 9 | Modified 2018 by Kevin Sheppard. Modifications licensed under the NCSA 10 | license. 11 | */ 12 | 13 | /* This is a fixed-increment version of Java 8's SplittableRandom generator 14 | See https://dx.doi.org/10.1145/2714064.2660195 and 15 | https://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html 16 | 17 | It is a very fast generator passing BigCrush, and it can be useful if 18 | for some reason you absolutely want 64 bits of state; otherwise, we 19 | rather suggest to use a xoroshiro128+ (for moderately parallel 20 | computations) or xorshift1024* (for massively parallel computations) 21 | generator. */ 22 | 23 | #include "splitmix64.h" 24 | 25 | extern inline uint64_t splitmix64_next(uint64_t *state); 26 | 27 | extern inline uint64_t splitmix64_next64(splitmix64_state *state); 28 | 29 | extern inline uint32_t splitmix64_next32(splitmix64_state *state); 30 | -------------------------------------------------------------------------------- /randomgen/src/splitmix64/splitmix64.h: -------------------------------------------------------------------------------- 1 | #include "../common/randomgen_config.h" 2 | 3 | typedef struct s_splitmix64_state { 4 | uint64_t state; 5 | int has_uint32; 6 | uint32_t uinteger; 7 | } splitmix64_state; 8 | 9 | static inline uint64_t splitmix64_next(uint64_t *state) { 10 | uint64_t z = (state[0] += 0x9e3779b97f4a7c15); 11 | z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; 12 | z = (z ^ (z >> 27)) * 0x94d049bb133111eb; 13 | return z ^ (z >> 31); 14 | } 15 | 16 | static inline uint64_t splitmix64_next64(splitmix64_state *state) { 17 | return splitmix64_next(&state->state); 18 | } 19 | 20 | static inline uint32_t splitmix64_next32(splitmix64_state *state) { 21 | uint64_t next; 22 | if (state->has_uint32) { 23 | state->has_uint32 = 0; 24 | return state->uinteger; 25 | } 26 | next = splitmix64_next64(state); 27 | state->has_uint32 = 1; 28 | state->uinteger = (uint32_t)(next >> 32); 29 | return (uint32_t)(next & 0xffffffff); 30 | } 31 | -------------------------------------------------------------------------------- /randomgen/src/splitmix64/splitmix64.orig.c: -------------------------------------------------------------------------------- 1 | /* Written in 2015 by Sebastiano Vigna (vigna@acm.org) 2 | 3 | To the extent possible under law, the author has dedicated all copyright 4 | and related and neighboring rights to this software to the public domain 5 | worldwide. This software is distributed without any warranty. 6 | 7 | See . */ 8 | 9 | #include 10 | 11 | /* This is a fixed-increment version of Java 8's SplittableRandom generator 12 | See https://dx.doi.org/10.1145/2714064.2660195 and 13 | https://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html 14 | 15 | It is a very fast generator passing BigCrush, and it can be useful if 16 | for some reason you absolutely want 64 bits of state; otherwise, we 17 | rather suggest to use a xoroshiro128+ (for moderately parallel 18 | computations) or xorshift1024* (for massively parallel computations) 19 | generator. */ 20 | 21 | uint64_t x; /* The state can be seeded with any value. */ 22 | 23 | uint64_t next() { 24 | uint64_t z = (x += 0x9e3779b97f4a7c15); 25 | z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; 26 | z = (z ^ (z >> 27)) * 0x94d049bb133111eb; 27 | return z ^ (z >> 31); 28 | } 29 | -------------------------------------------------------------------------------- /randomgen/src/squares/squares.c: -------------------------------------------------------------------------------- 1 | #include "squares.h" 2 | -------------------------------------------------------------------------------- /randomgen/src/squares/squares.orig.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef _SQUARES_H_ 4 | #define _SQUARES_H_ 5 | 6 | 7 | inline static uint32_t squares32(uint64_t key, uint64_t ctr) { 8 | uint64_t x, y, z; 9 | 10 | y = x = ctr * key; 11 | z = y + key; 12 | ctr++; 13 | x = x * x + y; 14 | x = (x >> 32) | (x << 32); 15 | x = x * x + z; 16 | x = (x >> 32) | (x << 32); 17 | x = x * x + y; 18 | x = (x >> 32) | (x << 32); 19 | return (x * x + z) >> 32; 20 | } 21 | 22 | inline static uint64_t squares64(uint64_t key, uint64_t ctr) { 23 | uint64_t t, x, y, z; 24 | y = x = ctr * key; 25 | z = y + key; 26 | ctr++; 27 | x = x * x + y; 28 | x = (x >> 32) | (x << 32); 29 | x = x * x + z; 30 | x = (x >> 32) | (x << 32); 31 | x = x * x + y; 32 | x = (x >> 32) | (x << 32); 33 | t = x = x * x + z; 34 | x = (x >> 32) | (x << 32); 35 | return t ^ ((x * x + y) >> 32); 36 | } 37 | 38 | #endif -------------------------------------------------------------------------------- /randomgen/src/threefry/LICENSE.md: -------------------------------------------------------------------------------- 1 | # THREEFRY 2 | 3 | Copyright 2010-2012, D. E. Shaw Research. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are 8 | met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions, and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions, and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | 17 | * Neither the name of D. E. Shaw Research nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /randomgen/src/threefry/threefry-benchmark.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple benchamrk command 3 | * 4 | * cl threefry-benchmark.c /Ox 5 | * 6 | * gcc threefry-benchmark.c -O3 -o threefry-benchmark 7 | * 8 | * Requres the Random123 directory containing header files to be located in the 9 | * same directory (not included). 10 | */ 11 | #include "Random123/threefry.h" 12 | #include 13 | #include 14 | #include 15 | 16 | #define N 1000000000 17 | 18 | int main() { 19 | threefry4x64_key_t ctr = {{0, 0, 0, 0}}; 20 | threefry4x64_ctr_t key = {{0xDEADBEAF, 0, 0, 0}}; 21 | threefry4x64_ctr_t out; 22 | uint64_t count = 0, sum = 0; 23 | int i, j; 24 | clock_t begin = clock(); 25 | for (i = 0; i < N / 4UL; i++) { 26 | ctr.v[0]++; 27 | out = threefry4x64_R(threefry4x64_rounds, ctr, key); 28 | for (j = 0; j < 4; j++) { 29 | sum += out.v[j]; 30 | count++; 31 | } 32 | } 33 | clock_t end = clock(); 34 | double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 35 | printf("0x%" PRIx64 "\ncount: %" PRIu64 "\n", sum, count); 36 | printf("%" PRIu64 " randoms per second\n", (uint64_t)((double)N / time_spent)); 37 | printf("%0.3f ms to produce 1,000,000 draws \n", 1000*1000000.0 * (time_spent/(double)N)); 38 | } 39 | -------------------------------------------------------------------------------- /randomgen/src/tyche/tyche-gen-test-data.cpp: -------------------------------------------------------------------------------- 1 | // cl /O2 tyche-gen-test-data.cpp -D__USE_ORIGINAL_TYCHE__ /EHsc 2 | // cl /O2 tyche-gen-test-data.cpp -D__USE_OPENRAND_TYCHE__ /EHsc 3 | 4 | #include "tyche.orig.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | #define N 1000 13 | 14 | #if !defined(__USE_OPENRAND_TYCHE__) && !defined(__USE_ORIGINAL_TYCHE__) 15 | error("No implementation selected for Tyche"); 16 | #endif 17 | 18 | #ifdef __USE_OPENRAND_TYCHE__ 19 | #define OUTPUT_FILE "tyche-openrand" 20 | #pragma message("Using openrand Tyche") 21 | #else 22 | #define OUTPUT_FILE "tyche" 23 | #pragma message("Using original Tyche") 24 | #endif 25 | 26 | int main() { 27 | clock_t t1, t2; 28 | uint64_t store[N]; 29 | uint64_t seedval = 15793235383387715774ULL; 30 | uint32_t idx = 745650761UL; 31 | auto tyche = openrand::Tyche(seedval, idx); 32 | std::ofstream ofile; 33 | ofile.open (OUTPUT_FILE "-testset-1.csv"); 34 | ofile << "seed, " << 0 <a = (uint32_t)(seed >> 32); 6 | state->b = (uint32_t)(seed & 0xFFFFFFFFULL); 7 | state->c = 2654435769; 8 | state->d = 1367130551 ^ idx; 9 | 10 | for (int i = 0; i < 20; i++) { 11 | if (original == 1) { 12 | mix(state); 13 | } else if (original == 0) { 14 | mix_openrand(state); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /randomgen/src/xoroshiro128/LICENSE.md: -------------------------------------------------------------------------------- 1 | # XOROSHIRO128 2 | 3 | Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org) 4 | 5 | To the extent possible under law, the author has dedicated all copyright 6 | and related and neighboring rights to this software to the public domain 7 | worldwide. This software is distributed without any warranty. 8 | 9 | See . -------------------------------------------------------------------------------- /randomgen/src/xoroshiro128/xoroshiro128-benchmark.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cl xoroshiro128-benchmark.c xoroshiro128plus.orig.c \ 3 | * ../splitmix64/splitmix64.c /Ox 4 | * 5 | * gcc -O3 xoroshiro128-benchmark.c xoroshiro128plus.orig.c \ 6 | * ../splitmix64/splitmix64.c -o xoroshiro128-benchmark 7 | * 8 | */ 9 | #include "../splitmix64/splitmix64.h" 10 | #include "xoroshiro128plus.orig.h" 11 | #include 12 | #include 13 | #include 14 | 15 | #define N 1000000000 16 | 17 | int main() 18 | { 19 | uint64_t count = 0, sum = 0; 20 | uint64_t seed = 0xDEADBEAF; 21 | s[0] = splitmix64_next(&seed); 22 | s[1] = splitmix64_next(&seed); 23 | int i; 24 | clock_t begin = clock(); 25 | for (i = 0; i < N; i++) 26 | { 27 | sum += next(); 28 | count++; 29 | } 30 | clock_t end = clock(); 31 | double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 32 | printf("0x%" PRIx64 "\ncount: %" PRIu64 "\n", sum, count); 33 | printf("%" PRIu64 " randoms per second\n", 34 | (uint64_t)(N / time_spent) / 1000000 * 1000000); 35 | } 36 | -------------------------------------------------------------------------------- /randomgen/src/xoroshiro128/xoroshiro128plus.orig.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uint64_t s[2]; 4 | uint64_t next(void); 5 | void jump(void); 6 | -------------------------------------------------------------------------------- /randomgen/src/xorshift1024/LICENSE.md: -------------------------------------------------------------------------------- 1 | # XORSHIFT1024 2 | 3 | Written in 2017 by Sebastiano Vigna (vigna@acm.org) 4 | 5 | To the extent possible under law, the author has dedicated all copyright 6 | and related and neighboring rights to this software to the public domain 7 | worldwide. This software is distributed without any warranty. 8 | 9 | See . -------------------------------------------------------------------------------- /randomgen/src/xorshift1024/xorshift1024-benchmark.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cl xorshift1024-benchmark.c xorshift2014.orig.c 3 | * ../splitmix64/splitmix64.c /Ox 4 | * 5 | * gcc -O3 xorshift1024-benchmark.c xorshift2014.orig.c / 6 | * ../splitmix64/splitmix64.c -o xorshift1024-benchmark 7 | * 8 | */ 9 | #include "../splitmix64/splitmix64.h" 10 | #include "xorshift1024.orig.h" 11 | #include 12 | #include 13 | #include 14 | 15 | #define N 1000000000 16 | 17 | int main() { 18 | uint64_t count = 0, sum = 0; 19 | uint64_t seed = 0xDEADBEAF; 20 | int i; 21 | for (i = 0; i < 16; i++) { 22 | s[i] = splitmix64_next(&seed); 23 | } 24 | p = 0; 25 | clock_t begin = clock(); 26 | for (i = 0; i < N; i++) { 27 | sum += next(); 28 | count++; 29 | } 30 | clock_t end = clock(); 31 | double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 32 | printf("0x%" PRIx64 "\ncount: %" PRIu64 "\n", sum, count); 33 | printf("%" PRIu64 " randoms per second\n", 34 | (uint64_t)(N / time_spent) / 1000000 * 1000000); 35 | } 36 | -------------------------------------------------------------------------------- /randomgen/src/xorshift1024/xorshift1024.c: -------------------------------------------------------------------------------- 1 | #include "xorshift1024.h" 2 | 3 | /* This is the jump function for the generator. It is equivalent 4 | to 2^512 calls to next(); it can be used to generate 2^512 5 | non-overlapping subsequences for parallel computations. */ 6 | 7 | extern INLINE uint64_t xorshift1024_next(xorshift1024_state_t *state); 8 | extern INLINE uint64_t xorshift1024_next64(xorshift1024_state_t *state); 9 | extern INLINE uint32_t xorshift1024_next32(xorshift1024_state_t *state); 10 | 11 | void xorshift1024_jump(xorshift1024_state_t *state) { 12 | int i, j, b; 13 | static const uint64_t JUMP[] = { 14 | 0x84242f96eca9c41d, 0xa3c65b8776f96855, 0x5b34a39f070b5837, 15 | 0x4489affce4f31a1e, 0x2ffeeb0a48316f40, 0xdc2d9891fe68c022, 16 | 0x3659132bb12fea70, 0xaac17d8efa43cab8, 0xc4cb815590989b13, 17 | 0x5ee975283d71c93b, 0x691548c86c1bd540, 0x7910c41d10a1e6a5, 18 | 0x0b5fc64563b3e2a8, 0x047f7684e9fc949d, 0xb99181f2d8f685ca, 19 | 0x284600e3f30e38c3}; 20 | 21 | uint64_t t[16] = {0}; 22 | for (i = 0; i < (int)(sizeof(JUMP) / sizeof(*JUMP)); i++) 23 | for (b = 0; b < 64; b++) { 24 | if (JUMP[i] & UINT64_C(1) << b) 25 | for (j = 0; j < 16; j++) 26 | t[j] ^= state->s[(j + state->p) & 15]; 27 | xorshift1024_next(state); 28 | } 29 | 30 | for (j = 0; j < 16; j++) 31 | state->s[(j + state->p) & 15] = t[j]; 32 | } 33 | -------------------------------------------------------------------------------- /randomgen/src/xorshift1024/xorshift1024.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__XORSHIFT1024_H_ 2 | #define _RANDOMDGEN__XORSHIFT1024_H_ 3 | 4 | #include "../common/randomgen_config.h" 5 | 6 | typedef struct XORSHIFT1024_STATE_T { 7 | uint64_t s[16]; 8 | int p; 9 | int has_uint32; 10 | uint32_t uinteger; 11 | } xorshift1024_state_t; 12 | 13 | static INLINE uint64_t xorshift1024_next(xorshift1024_state_t *state) { 14 | const uint64_t s0 = state->s[state->p]; 15 | uint64_t s1 = state->s[state->p = ((state->p) + 1) & 15]; 16 | s1 ^= s1 << 31; // a 17 | state->s[state->p] = s1 ^ s0 ^ (s1 >> 11) ^ (s0 >> 30); // b,c 18 | return state->s[state->p] * 0x9e3779b97f4a7c13; 19 | } 20 | 21 | static INLINE uint64_t xorshift1024_next64(xorshift1024_state_t *state) { 22 | return xorshift1024_next(state); 23 | } 24 | 25 | static INLINE uint32_t xorshift1024_next32(xorshift1024_state_t *state) { 26 | uint64_t next; 27 | if (state->has_uint32) { 28 | state->has_uint32 = 0; 29 | return state->uinteger; 30 | } 31 | next = xorshift1024_next(state); 32 | state->has_uint32 = 1; 33 | state->uinteger = (uint32_t)(next >> 32); 34 | return (uint32_t)(next & 0xffffffff); 35 | } 36 | 37 | void xorshift1024_jump(xorshift1024_state_t *state); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /randomgen/src/xorshift1024/xorshift1024.orig.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | uint64_t s[16]; 5 | int p; 6 | uint64_t next(void); 7 | void jump(void); 8 | -------------------------------------------------------------------------------- /randomgen/src/xoshiro256/LICENSE.md: -------------------------------------------------------------------------------- 1 | # XOSHIRO256 2 | 3 | Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) 4 | 5 | To the extent possible under law, the author has dedicated all copyright 6 | and related and neighboring rights to this software to the public domain 7 | worldwide. This software is distributed without any warranty. 8 | 9 | See . -------------------------------------------------------------------------------- /randomgen/src/xoshiro256/xoshiro256-benchmark-indirect.c: -------------------------------------------------------------------------------- 1 | /* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) 2 | 3 | To the extent possible under law, the author has dedicated all copyright 4 | and related and neighboring rights to this software to the public domain 5 | worldwide. This software is distributed without any warranty. 6 | 7 | See . */ 8 | 9 | #include "xoshiro256.h" 10 | #include 11 | #include 12 | 13 | #define N 1000000000 14 | int main() 15 | { 16 | xoshiro256_state_t state; 17 | state.s[0] = 12349123LL; 18 | state.s[1] = 9812839737LL; 19 | state.s[2] = 1289983092813174LL; 20 | state.s[3] = 12899830928131741LL; 21 | uint64_t sum = 0; 22 | int i; 23 | clock_t begin = clock(); 24 | for (int i = 0; i < N; i++) 25 | { 26 | sum += xoshiro256_next64(&state); 27 | } 28 | clock_t end = clock(); 29 | double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 30 | printf("0x%" PRIx64 "\ncount: %" PRIu64 "\n", sum, (uint64_t)N); 31 | printf("%" PRIu64 " randoms per second\n", 32 | (uint64_t)((double)N / time_spent)); 33 | printf("%0.3f ms to produce 1,000,000 draws \n", 34 | 1000. * (1000000.0 * (time_spent / (double)N))); 35 | } 36 | -------------------------------------------------------------------------------- /randomgen/src/xoshiro256/xoshiro256.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__XOSHIRO256_H_ 2 | #define _RANDOMDGEN__XOSHIRO256_H_ 3 | 4 | #include "../common/randomgen_config.h" 5 | 6 | typedef struct XOSHIRO256_STATE_T { 7 | uint64_t s[4]; 8 | int has_uint32; 9 | uint32_t uinteger; 10 | } xoshiro256_state_t; 11 | 12 | static INLINE uint64_t rotl(const uint64_t x, int k) { 13 | return (x << k) | (x >> (64 - k)); 14 | } 15 | 16 | static INLINE uint64_t xoshiro256_next(uint64_t *s) { 17 | const uint64_t result_starstar = rotl(s[1] * 5, 7) * 9; 18 | const uint64_t t = s[1] << 17; 19 | 20 | s[2] ^= s[0]; 21 | s[3] ^= s[1]; 22 | s[1] ^= s[2]; 23 | s[0] ^= s[3]; 24 | 25 | s[2] ^= t; 26 | 27 | s[3] = rotl(s[3], 45); 28 | 29 | return result_starstar; 30 | } 31 | 32 | static INLINE uint64_t 33 | xoshiro256_next64(xoshiro256_state_t *state) { 34 | return xoshiro256_next(&state->s[0]); 35 | } 36 | 37 | static INLINE uint32_t 38 | xoshiro256_next32(xoshiro256_state_t *state) { 39 | uint64_t next; 40 | if (state->has_uint32) { 41 | state->has_uint32 = 0; 42 | return state->uinteger; 43 | } 44 | next = xoshiro256_next(&state->s[0]); 45 | state->has_uint32 = 1; 46 | state->uinteger = (uint32_t)(next >> 32); 47 | return (uint32_t)(next & 0xffffffff); 48 | } 49 | 50 | void xoshiro256_jump(xoshiro256_state_t *state); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /randomgen/src/xoshiro256/xoshiro256.orig.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uint64_t s[4]; 4 | uint64_t next(void); 5 | void jump(void); 6 | -------------------------------------------------------------------------------- /randomgen/src/xoshiro512/LICENSE.md: -------------------------------------------------------------------------------- 1 | # XOSHIRO512 2 | 3 | Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) 4 | 5 | To the extent possible under law, the author has dedicated all copyright 6 | and related and neighboring rights to this software to the public domain 7 | worldwide. This software is distributed without any warranty. 8 | 9 | See . 10 | -------------------------------------------------------------------------------- /randomgen/src/xoshiro512/xoshiro512.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANDOMDGEN__XOSHIRO512_H_ 2 | #define _RANDOMDGEN__XOSHIRO512_H_ 3 | 4 | #include "../common/randomgen_config.h" 5 | 6 | typedef struct XOSHIRO512_STATE_T 7 | { 8 | uint64_t s[8]; 9 | int has_uint32; 10 | uint32_t uinteger; 11 | } xoshiro512_state_t; 12 | 13 | static INLINE uint64_t rotl(const uint64_t x, int k) 14 | { 15 | return (x << k) | (x >> (64 - k)); 16 | } 17 | 18 | static INLINE uint64_t xoshiro512_next(uint64_t *s) 19 | { 20 | const uint64_t result_starstar = rotl(s[1] * 5, 7) * 9; 21 | 22 | const uint64_t t = s[1] << 11; 23 | 24 | s[2] ^= s[0]; 25 | s[5] ^= s[1]; 26 | s[1] ^= s[2]; 27 | s[7] ^= s[3]; 28 | s[3] ^= s[4]; 29 | s[4] ^= s[5]; 30 | s[0] ^= s[6]; 31 | s[6] ^= s[7]; 32 | 33 | s[6] ^= t; 34 | 35 | s[7] = rotl(s[7], 21); 36 | 37 | return result_starstar; 38 | } 39 | 40 | static INLINE uint64_t 41 | xoshiro512_next64(xoshiro512_state_t *state) 42 | { 43 | return xoshiro512_next(&state->s[0]); 44 | } 45 | 46 | static INLINE uint32_t 47 | xoshiro512_next32(xoshiro512_state_t *state) 48 | { 49 | uint64_t next; 50 | if (state->has_uint32) 51 | { 52 | state->has_uint32 = 0; 53 | return state->uinteger; 54 | } 55 | next = xoshiro512_next(&state->s[0]); 56 | state->has_uint32 = 1; 57 | state->uinteger = (uint32_t)(next >> 32); 58 | return (uint32_t)(next & 0xffffffff); 59 | } 60 | 61 | void xoshiro512_jump(xoshiro512_state_t *state); 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /randomgen/src/xoshiro512/xoshiro512.orig.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | uint64_t s[8]; 5 | uint64_t next(void); 6 | void jump(void); 7 | -------------------------------------------------------------------------------- /randomgen/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bashtage/randomgen/34bc41ac41b94a0df9806fdd4ed242531b520e3a/randomgen/tests/__init__.py -------------------------------------------------------------------------------- /randomgen/tests/_shim_dist.c: -------------------------------------------------------------------------------- 1 | #include "_shim_dist.h" 2 | 3 | double double0_func(bitgen_t *state) { return 3.141592; } 4 | 5 | double double1_func(bitgen_t *state, double a) { return a; } 6 | 7 | double double2_func(bitgen_t *state, double a, double b) { return a + b; } 8 | 9 | double double3_func(bitgen_t *state, double a, double b, double c) { 10 | return a + b + c; 11 | } 12 | 13 | float float_0(bitgen_t *state) { return 3.141592; } 14 | 15 | float float_1(bitgen_t *state, float a) { return a; } 16 | 17 | int64_t int_0(void *state) { return 3; } 18 | 19 | int64_t int_d(void *state, double a) { return (int64_t)(10 * a); }; 20 | 21 | int64_t int_dd(void *state, double a, double b) { 22 | return (int64_t)(10 * a * b); 23 | }; 24 | 25 | int64_t int_di(void *state, double a, uint64_t b) { 26 | return (int64_t)2 * a * b; 27 | }; 28 | 29 | int64_t int_i(void *state, int64_t a) { return a; }; 30 | 31 | int64_t int_iii(void *state, int64_t a, int64_t b, int64_t c) { 32 | return a + b + c; 33 | }; 34 | -------------------------------------------------------------------------------- /randomgen/tests/_shim_dist.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "numpy/random/distributions.h" 3 | 4 | extern double double0_func(bitgen_t *state); 5 | extern double double1_func(bitgen_t *state, double a); 6 | extern double double2_func(bitgen_t *state, double a, double b); 7 | extern double double3_func(bitgen_t *state, double a, double b, double c); 8 | 9 | extern float float_0(bitgen_t *state); 10 | extern float float_1(bitgen_t *state, float a); 11 | 12 | extern int64_t int_0(void *state); 13 | extern int64_t int_d(void *state, double a); 14 | extern int64_t int_dd(void *state, double a, double b); 15 | extern int64_t int_di(void *state, double a, uint64_t b); 16 | extern int64_t int_i(void *state, int64_t a); 17 | extern int64_t int_iii(void *state, int64_t a, int64_t b, int64_t c); 18 | 19 | /* 20 | extern uint32_t uint_0_32(bitgen_t *state); 21 | extern uint32_t uint_1_i_32(bitgen_t *state, uint32_t a); 22 | 23 | extern int32_t int_2_i_32(bitgen_t *state, int32_t a, int32_t b); 24 | extern int64_t int_2_i(bitgen_t *state, int64_t a, int64_t b); 25 | */ -------------------------------------------------------------------------------- /randomgen/tests/_shims.pxd: -------------------------------------------------------------------------------- 1 | from cpython.pycapsule cimport PyCapsule_GetPointer, PyCapsule_IsValid 2 | from numpy.random cimport bitgen_t 3 | 4 | from randomgen.broadcasting cimport ( 5 | constraint_type, 6 | cont, 7 | cont_f, 8 | disc, 9 | float_fill_from_double, 10 | ) 11 | from randomgen.common cimport ( 12 | byteswap_little_endian, 13 | int_to_array, 14 | object_to_int, 15 | view_little_endian, 16 | ) 17 | 18 | from Cython.Includes.cpython.datetime import noexcept 19 | 20 | from libc.stdint cimport int64_t, uint64_t 21 | 22 | 23 | cdef extern from "_shim_dist.h": 24 | double double0_func(bitgen_t *state) noexcept nogil 25 | double double1_func(bitgen_t *state, double a) noexcept nogil 26 | double double2_func(bitgen_t *state, double a, double b) noexcept nogil 27 | double double3_func(bitgen_t *state, double a, double b, double c) noexcept nogil 28 | 29 | float float_0(bitgen_t *state) noexcept nogil 30 | float float_1(bitgen_t *state, float a) noexcept nogil 31 | 32 | int64_t int_0(bitgen_t *state) noexcept nogil 33 | int64_t int_d(bitgen_t *state, double a) noexcept nogil 34 | int64_t int_dd(bitgen_t *state, double a, double b) noexcept nogil 35 | int64_t int_di(bitgen_t *state, double a, uint64_t b) noexcept nogil 36 | int64_t int_i(bitgen_t *state, int64_t a) noexcept nogil 37 | int64_t int_iii(bitgen_t *state, int64_t a, int64_t b, int64_t c) noexcept nogil 38 | -------------------------------------------------------------------------------- /randomgen/tests/_shims.pyi: -------------------------------------------------------------------------------- 1 | from collections.abc import Sequence 2 | from typing import Literal 3 | 4 | import numpy as np 5 | 6 | def view_little_endian_shim(arr: np.ndarray, dtype: str) -> np.ndarray: ... 7 | def int_to_array_shim( 8 | value: int, name: str, bits: int, uint_size: Literal[32, 64] 9 | ) -> np.ndarray: ... 10 | def byteswap_little_endian_shim(arr: np.ndarray) -> np.ndarray: ... 11 | def object_to_int_shim( 12 | val: int | np.ndarray | Sequence[int], 13 | bits: int, 14 | name: str, 15 | default_bits: Literal[32, 64] = ..., 16 | allowed_sizes: tuple[int] | tuple[int, int] = ..., 17 | ) -> int: ... 18 | -------------------------------------------------------------------------------- /randomgen/tests/data/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bashtage/randomgen/34bc41ac41b94a0df9806fdd4ed242531b520e3a/randomgen/tests/data/__init__.py -------------------------------------------------------------------------------- /randomgen/tests/data/_write_hashes.py: -------------------------------------------------------------------------------- 1 | if __name__ == "__main__": 2 | from randomgen.tests.data.compute_hashes import ( 3 | final_configurations, 4 | hash_configuration, 5 | ) 6 | 7 | computed_hashes = {} 8 | for key in final_configurations: 9 | computed_hashes[key] = hash_configuration(final_configurations[key]) 10 | 11 | import black 12 | 13 | fm = black.FileMode({black.TargetVersion.PY37, black.TargetVersion.PY38}) 14 | out = black.format_file_contents( 15 | "import numpy as np\n\n" + "known_hashes = " + str(dict(computed_hashes)), 16 | fast=True, 17 | mode=fm, 18 | ) 19 | with open("stable_hashes.py", "w") as results: 20 | results.write(out) 21 | -------------------------------------------------------------------------------- /randomgen/tests/data/ctypes_testing.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uint64_t output_upper(uint64_t a, uint64_t b) { 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /randomgen/tests/test_bit_generators_against_numpy.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from packaging.version import parse 3 | import pytest 4 | 5 | import randomgen 6 | from randomgen import PCG64, SFC64, Philox, SeedSequence 7 | 8 | NP_LT_119 = parse(np.__version__) < parse("1.19.0") 9 | 10 | pytestmark = pytest.mark.skipif(NP_LT_119, reason="Only test Numpy 1.19+") 11 | 12 | 13 | @pytest.mark.parametrize("bg", ["SFC64", "MT19937", "PCG64", "Philox"]) 14 | def test_against_numpy(bg): 15 | bitgen = getattr(randomgen, bg) 16 | np_bitgen = getattr(np.random, bg) 17 | ss = np.random.SeedSequence(1203940) 18 | np_ss = np.random.SeedSequence(1203940) 19 | kwargs = {"variant": "xsl-rr"} if bg == "PCG64" else {} 20 | ref = bitgen(ss, numpy_seed=True, **kwargs) 21 | exp = np_bitgen(np_ss) 22 | np.testing.assert_equal(ref.random_raw(1000), exp.random_raw(1000)) 23 | 24 | 25 | def test_pcg_numpy_mode_exception(): 26 | with pytest.raises(ValueError): 27 | PCG64(SeedSequence(0), numpy_seed=True, inc=3) 28 | 29 | 30 | @pytest.mark.parametrize("k", [1, 4]) 31 | @pytest.mark.parametrize("w", [1, 3]) 32 | def test_sfc_numpy_mode_exception(k, w): 33 | if k == w == 1: 34 | return 35 | with pytest.raises(ValueError): 36 | SFC64(SeedSequence(0), numpy_seed=True, w=w, k=k) 37 | 38 | 39 | @pytest.mark.parametrize("number", [2, 4]) 40 | @pytest.mark.parametrize("width", [32, 64]) 41 | def test_philox_numpy_mode_exception(number, width): 42 | if number == 4 and width == 64: 43 | return 44 | with pytest.raises(ValueError): 45 | Philox(SeedSequence(0), numpy_seed=True, number=number, width=width) 46 | -------------------------------------------------------------------------------- /randomgen/tests/test_final_release_changes.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from randomgen import ( 4 | DSFMT, 5 | MT19937, 6 | PCG32, 7 | PCG64, 8 | Philox, 9 | ThreeFry, 10 | Xoroshiro128, 11 | Xorshift1024, 12 | Xoshiro256, 13 | Xoshiro512, 14 | ) 15 | 16 | bit_generators = [ 17 | DSFMT, 18 | MT19937, 19 | PCG32, 20 | PCG64, 21 | Philox, 22 | ThreeFry, 23 | Xoroshiro128, 24 | Xorshift1024, 25 | Xoshiro256, 26 | Xoshiro512, 27 | ] 28 | 29 | 30 | @pytest.fixture(scope="module", params=bit_generators) 31 | def bit_generator(request): 32 | return request.param 33 | 34 | 35 | @pytest.fixture(scope="module", params=[True, False]) 36 | def endpoint(request): 37 | return request.param 38 | 39 | 40 | def test_generator_raises(bit_generator): 41 | bg = bit_generator() 42 | with pytest.raises(NotImplementedError): 43 | bg.generator 44 | -------------------------------------------------------------------------------- /randomgen/tests/test_sfc.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | 4 | from randomgen import SFC64, SeedSequence 5 | 6 | 7 | def test_known(): 8 | sfc = SFC64(SeedSequence(0)) 9 | weyl = sfc.weyl_increments(2) 10 | expected = np.array([6524879303493105881, 17467897594175157085], dtype=np.uint64) 11 | np.testing.assert_equal(weyl, expected) 12 | weyl = sfc.weyl_increments(2, 48, 16) 13 | expected = np.array([18331436834911646537, 1349527966119344023], dtype=np.uint64) 14 | np.testing.assert_equal(weyl, expected) 15 | 16 | 17 | def test_validity(): 18 | sfc = SFC64(SeedSequence()) 19 | weyl = sfc.weyl_increments(10000) 20 | weyl = weyl.reshape((-1, 1)) 21 | bits = np.unpackbits(weyl.view("u1"), axis=1) 22 | assert (bits.sum(1) == 32).all() 23 | assert (weyl % np.uint64(2) == 1).all() 24 | 25 | weyl = sfc.weyl_increments(10000, 40, 24) 26 | weyl = weyl.reshape((-1, 1)) 27 | bits = np.unpackbits(weyl.view("u1"), axis=1) 28 | assert (bits.sum(1) <= 40).all() 29 | assert (bits.sum(1) >= 24).all() 30 | assert (weyl % np.uint64(2) == 1).all() 31 | 32 | 33 | def test_smoke(): 34 | sfc = SFC64(SeedSequence(0)) 35 | for max_bit in range(1, 64): 36 | for min_bit in range(1, max_bit + 1): 37 | weyl = sfc.weyl_increments(1, max_bit, min_bit) 38 | assert weyl % 2 == 1 39 | 40 | 41 | def test_invalid_weyl(): 42 | sfc = SFC64(SeedSequence(0)) 43 | with pytest.raises(ValueError): 44 | sfc.weyl_increments(1000, 1, 1) 45 | with pytest.raises(ValueError): 46 | sfc.weyl_increments(1, 32, 33) 47 | with pytest.raises(ValueError): 48 | sfc.weyl_increments(1, 32, -1) 49 | with pytest.raises(ValueError): 50 | sfc.weyl_increments(1, 128) 51 | with pytest.raises(ValueError): 52 | sfc.weyl_increments(0) 53 | with pytest.warns(RuntimeWarning): 54 | sfc.weyl_increments(40, 2) 55 | -------------------------------------------------------------------------------- /randomgen/threefry.pyi: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed, SeedMode 5 | 6 | class ThreeFry(BitGenerator): 7 | def __init__( 8 | self, 9 | seed: IntegerSequenceSeed | None = ..., 10 | *, 11 | counter: int | np.ndarray | None = ..., 12 | key: int | np.ndarray | None = ..., 13 | number: int = ..., 14 | width: int = ..., 15 | mode: SeedMode | None = ... 16 | ) -> None: ... 17 | def seed( 18 | self, 19 | seed: IntegerSequenceSeed | None = ..., 20 | counter: int | np.ndarray | None = ..., 21 | key: int | np.ndarray | None = ..., 22 | ) -> None: ... 23 | @property 24 | def state( 25 | self, 26 | ) -> dict[str, str | int | np.ndarray | dict[str, np.ndarray]]: ... 27 | @state.setter 28 | def state( 29 | self, value: dict[str, str | int | np.ndarray | dict[str, np.ndarray]] 30 | ) -> None: ... 31 | def jump(self, iter: int = ...) -> ThreeFry: ... 32 | def jumped(self, iter: int = ...) -> ThreeFry: ... 33 | def advance(self, delta: int, counter: bool | None = ...) -> ThreeFry: ... 34 | -------------------------------------------------------------------------------- /randomgen/tyche.pxd: -------------------------------------------------------------------------------- 1 | 2 | 3 | cimport numpy as np 4 | from libc.stdint cimport uint32_t, uint64_t 5 | 6 | from randomgen.common cimport BitGenerator, check_state_array, fully_qualified_name 7 | 8 | 9 | cdef extern from "src/tyche/tyche.h": 10 | 11 | struct TYCHE_STATE_T: 12 | uint32_t a 13 | uint32_t b 14 | uint32_t c 15 | uint32_t d 16 | 17 | ctypedef TYCHE_STATE_T tyche_state_t 18 | 19 | uint64_t tyche_next64(tyche_state_t *state) noexcept nogil 20 | uint32_t tyche_next32(tyche_state_t *state) noexcept nogil 21 | double tyche_next_double(tyche_state_t *state) noexcept nogil 22 | uint64_t tyche_openrand_next64(tyche_state_t *state) noexcept nogil 23 | uint32_t tyche_openrand_next32(tyche_state_t *state) noexcept nogil 24 | double tyche_openrand_next_double(tyche_state_t *state) noexcept nogil 25 | 26 | void tyche_seed(tyche_state_t *state, uint64_t seed, uint32_t inc, int openrand) noexcept nogil 27 | 28 | 29 | 30 | cdef class Tyche(BitGenerator): 31 | cdef bint original 32 | cdef tyche_state_t rng_state 33 | cdef void _setup_bitgen(self) 34 | -------------------------------------------------------------------------------- /randomgen/tyche.pyi: -------------------------------------------------------------------------------- 1 | from randomgen.common import BitGenerator 2 | from randomgen.typing import IntegerSequenceSeed 3 | 4 | class Tyche(BitGenerator): 5 | def __init__( 6 | self, seed: IntegerSequenceSeed | None = ..., *, idx: int | None = ... 7 | ) -> None: ... 8 | def seed( 9 | self, seed: IntegerSequenceSeed | None = ..., *, idx: int | None = ... 10 | ) -> None: ... 11 | @property 12 | def state( 13 | self, 14 | ) -> dict[str, str | dict[str, int]]: ... 15 | @state.setter 16 | def state(self, value: dict[str, str | dict[str, int]]) -> None: ... 17 | -------------------------------------------------------------------------------- /randomgen/typing.py: -------------------------------------------------------------------------------- 1 | from collections.abc import Sequence 2 | from typing import Literal, Optional, Union 3 | 4 | from randomgen.seed_sequence import SeedSequence 5 | 6 | SeedMode = Literal["sequence"] 7 | 8 | __all__ = ["IntegerSequenceSeed", "SeedMode", "Size"] 9 | 10 | IntegerSequenceSeed = Union[int, Sequence[int], SeedSequence] 11 | 12 | RequiredSize = int | Sequence[int] 13 | Size = Optional[RequiredSize] 14 | -------------------------------------------------------------------------------- /randomgen/wrapper.pyi: -------------------------------------------------------------------------------- 1 | from collections.abc import Callable 2 | from ctypes import c_void_p 3 | from typing import Any, Literal 4 | 5 | from numba.core.ccallback import CFunc 6 | 7 | from randomgen.common import BitGenerator 8 | 9 | class UserBitGenerator(BitGenerator): 10 | def __init__( 11 | self, 12 | next_raw: Callable[[int], int] | None, 13 | bits: Literal[32, 64] = ..., 14 | next_64: Callable[[int], int] | None = ..., 15 | next_32: Callable[[int], int] | None = ..., 16 | next_double: Callable[[int], float] | None = ..., 17 | state: int | None = ..., 18 | state_getter: Callable[[], Any] | None = ..., 19 | state_setter: Callable[[Any], None] | None = ..., 20 | ) -> None: ... 21 | @property 22 | def state(self) -> Any: ... 23 | @state.setter 24 | def state(self, value: Any) -> None: ... 25 | @classmethod 26 | def from_cfunc( 27 | cls, 28 | next_raw: CFunc, 29 | next_64: CFunc, 30 | next_32: CFunc, 31 | next_double: CFunc, 32 | state: int, 33 | state_getter: Callable[[], Any] | None = ..., 34 | state_setter: Callable[[Any], None] | None = ..., 35 | ) -> UserBitGenerator: ... 36 | @classmethod 37 | def from_ctypes( 38 | cls, 39 | next_raw: Any, 40 | next_64: Any, 41 | next_32: Any, 42 | next_double: Any, 43 | state: c_void_p, 44 | state_getter: Callable[[], Any] | None = ..., 45 | state_setter: Callable[[Any], None] | None = ..., 46 | ) -> UserBitGenerator: ... 47 | -------------------------------------------------------------------------------- /randomgen/xoroshiro128.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport uint32_t, uint64_t 3 | 4 | from randomgen.common cimport ( 5 | BitGenerator, 6 | check_state_array, 7 | fully_qualified_name, 8 | uint64_to_double, 9 | ) 10 | 11 | 12 | cdef extern from "src/xoroshiro128/xoroshiro128.h": 13 | 14 | struct XOROSHIRO128_STATE_T: 15 | uint64_t s[2] 16 | int has_uint32 17 | uint32_t uinteger 18 | 19 | ctypedef XOROSHIRO128_STATE_T xoroshiro128_state_t 20 | 21 | uint64_t xoroshiro128_next64(xoroshiro128_state_t *state) noexcept nogil 22 | uint32_t xoroshiro128_next32(xoroshiro128_state_t *state) noexcept nogil 23 | void xoroshiro128_jump(xoroshiro128_state_t *state) 24 | 25 | uint64_t xoroshiro128plusplus_next64(xoroshiro128_state_t *state) noexcept nogil 26 | uint32_t xoroshiro128plusplus_next32(xoroshiro128_state_t *state) noexcept nogil 27 | void xoroshiro128plusplus_jump(xoroshiro128_state_t *state) 28 | 29 | 30 | cdef class Xoroshiro128(BitGenerator): 31 | 32 | cdef xoroshiro128_state_t rng_state 33 | cdef bint _plusplus 34 | cdef _reset_state_variables(self) 35 | cdef _set_generators(self) 36 | cdef jump_inplace(self, np.npy_intp iter) 37 | -------------------------------------------------------------------------------- /randomgen/xoroshiro128.pyi: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed, SeedMode 5 | 6 | class Xoroshiro128(BitGenerator): 7 | def __init__( 8 | self, 9 | seed: IntegerSequenceSeed | None = ..., 10 | *, 11 | mode: SeedMode = ..., 12 | plusplus: bool = ... 13 | ) -> None: ... 14 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 15 | def jump(self, iter: int = ...) -> Xoroshiro128: ... 16 | def jumped(self, iter: int = ...) -> Xoroshiro128: ... 17 | @property 18 | def state(self) -> dict[str, str | np.ndarray | bool | int]: ... 19 | @state.setter 20 | def state(self, value: dict[str, str | np.ndarray | bool | int]) -> None: ... 21 | -------------------------------------------------------------------------------- /randomgen/xorshift1024.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport uint32_t, uint64_t 3 | 4 | from randomgen.common cimport ( 5 | BitGenerator, 6 | check_state_array, 7 | fully_qualified_name, 8 | uint64_to_double, 9 | ) 10 | 11 | 12 | cdef extern from "src/xorshift1024/xorshift1024.h": 13 | 14 | struct XORSHIFT1024_STATE_T: 15 | uint64_t s[16] 16 | int p 17 | int has_uint32 18 | uint32_t uinteger 19 | 20 | ctypedef XORSHIFT1024_STATE_T xorshift1024_state_t 21 | 22 | uint64_t xorshift1024_next64(xorshift1024_state_t *state) noexcept nogil 23 | uint32_t xorshift1024_next32(xorshift1024_state_t *state) noexcept nogil 24 | void xorshift1024_jump(xorshift1024_state_t *state) 25 | 26 | 27 | cdef class Xorshift1024(BitGenerator): 28 | 29 | cdef xorshift1024_state_t rng_state 30 | cdef _reset_state_variables(self) 31 | cdef jump_inplace(self, np.npy_intp iter) 32 | -------------------------------------------------------------------------------- /randomgen/xorshift1024.pyi: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed, SeedMode 5 | 6 | class Xorshift1024(BitGenerator): 7 | def __init__( 8 | self, seed: IntegerSequenceSeed | None = ..., *, mode: SeedMode = ... 9 | ) -> None: ... 10 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 11 | def jump(self, iter: int = ...) -> Xorshift1024: ... 12 | def jumped(self, iter: int = ...) -> Xorshift1024: ... 13 | @property 14 | def state( 15 | self, 16 | ) -> dict[str, str | dict[str, int | np.ndarray] | int]: ... 17 | @state.setter 18 | def state( 19 | self, value: dict[str, str | dict[str, int | np.ndarray] | int] 20 | ) -> None: ... 21 | -------------------------------------------------------------------------------- /randomgen/xoshiro256.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport uint32_t, uint64_t 3 | 4 | from randomgen.common cimport ( 5 | BitGenerator, 6 | check_state_array, 7 | fully_qualified_name, 8 | uint64_to_double, 9 | ) 10 | 11 | 12 | cdef extern from "src/xoshiro256/xoshiro256.h": 13 | 14 | struct XOSHIRO256_STATE_T: 15 | uint64_t s[8] 16 | int has_uint32 17 | uint32_t uinteger 18 | 19 | ctypedef XOSHIRO256_STATE_T xoshiro256_state_t 20 | 21 | uint64_t xoshiro256_next64(xoshiro256_state_t *state) noexcept nogil 22 | uint32_t xoshiro256_next32(xoshiro256_state_t *state) noexcept nogil 23 | void xoshiro256_jump(xoshiro256_state_t *state) 24 | 25 | 26 | cdef class Xoshiro256(BitGenerator): 27 | 28 | cdef xoshiro256_state_t rng_state 29 | cdef _reset_state_variables(self) 30 | cdef jump_inplace(self, np.npy_intp iter) 31 | -------------------------------------------------------------------------------- /randomgen/xoshiro256.pyi: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed, SeedMode 5 | 6 | class Xoshiro256(BitGenerator): 7 | def __init__( 8 | self, seed: IntegerSequenceSeed | None = ..., *, mode: SeedMode = ... 9 | ) -> None: ... 10 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 11 | def jump(self, iter: int = ...) -> Xoshiro256: ... 12 | def jumped(self, iter: int = ...) -> Xoshiro256: ... 13 | @property 14 | def state(self) -> dict[str, str | np.ndarray | int]: ... 15 | @state.setter 16 | def state(self, value: dict[str, str | np.ndarray | int]) -> None: ... 17 | -------------------------------------------------------------------------------- /randomgen/xoshiro512.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | from libc.stdint cimport uint32_t, uint64_t 3 | 4 | from randomgen.common cimport ( 5 | BitGenerator, 6 | check_state_array, 7 | fully_qualified_name, 8 | uint64_to_double, 9 | ) 10 | 11 | 12 | cdef extern from "src/xoshiro512/xoshiro512.h": 13 | 14 | struct XOSHIRO512_STATE_T: 15 | uint64_t s[8] 16 | int has_uint32 17 | uint32_t uinteger 18 | 19 | ctypedef XOSHIRO512_STATE_T xoshiro512_state_t 20 | 21 | uint64_t xoshiro512_next64(xoshiro512_state_t *state) noexcept nogil 22 | uint32_t xoshiro512_next32(xoshiro512_state_t *state) noexcept nogil 23 | void xoshiro512_jump(xoshiro512_state_t *state) 24 | 25 | 26 | cdef class Xoshiro512(BitGenerator): 27 | 28 | cdef xoshiro512_state_t rng_state 29 | cdef _reset_state_variables(self) 30 | cdef jump_inplace(self, np.npy_intp iter) 31 | -------------------------------------------------------------------------------- /randomgen/xoshiro512.pyi: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from randomgen.common import BitGenerator 4 | from randomgen.typing import IntegerSequenceSeed, SeedMode 5 | 6 | class Xoshiro512(BitGenerator): 7 | def __init__( 8 | self, seed: IntegerSequenceSeed | None = ..., *, mode: SeedMode = ... 9 | ) -> None: ... 10 | def seed(self, seed: IntegerSequenceSeed | None = ...) -> None: ... 11 | def jump(self, iter: int = ...) -> Xoshiro512: ... 12 | def jumped(self, iter: int = ...) -> Xoshiro512: ... 13 | @property 14 | def state(self) -> dict[str, str | np.ndarray | int]: ... 15 | @state.setter 16 | def state(self, value: dict[str, str | np.ndarray | int]) -> None: ... 17 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | # Build 2 | cython>=3.0.10 3 | # Testing 4 | pytest>=7 5 | pytest-cov 6 | pytest-xdist 7 | scipy>=1.13.1 8 | # Lint 9 | black[jupyter]~=24.8.0 10 | isort~=5.0 11 | setuptools_scm[toml]>=8.0.0,<9.0.0 12 | ruff 13 | flake8 14 | flake8-pyi 15 | zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability 16 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy>=1.22.3 2 | setuptools 3 | wheel 4 | -------------------------------------------------------------------------------- /tools/configuration.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | import jinja2 4 | 5 | from randomgen import ( 6 | DSFMT, 7 | EFIIX64, 8 | HC128, 9 | JSF, 10 | LXM, 11 | MT19937, 12 | PCG64, 13 | SFC64, 14 | SFMT, 15 | SPECK128, 16 | AESCounter, 17 | ChaCha, 18 | LCG128Mix, 19 | Philox, 20 | Romu, 21 | ThreeFry, 22 | Xoshiro256, 23 | Xoshiro512, 24 | ) 25 | 26 | ALL_BIT_GENS = [ 27 | AESCounter, 28 | ChaCha, 29 | DSFMT, 30 | EFIIX64, 31 | HC128, 32 | JSF, 33 | LXM, 34 | PCG64, 35 | LCG128Mix, 36 | MT19937, 37 | Philox, 38 | SFC64, 39 | SFMT, 40 | SPECK128, 41 | ThreeFry, 42 | Xoshiro256, 43 | Xoshiro512, 44 | Romu, 45 | ] 46 | JUMPABLE = [bg for bg in ALL_BIT_GENS if hasattr(bg, "jumped")] 47 | 48 | SPECIALS = { 49 | ChaCha: {"rounds": [8, 20]}, 50 | JSF: {"seed_size": [1, 3]}, 51 | SFC64: {"k": [1, 3394385948627484371, "weyl"]}, 52 | LCG128Mix: {"output": ["upper"]}, 53 | PCG64: {"variant": ["dxsm", "dxsm-128", "xsl-rr"]}, 54 | Romu: {"variant": ["quad", "trio"]}, 55 | } 56 | OUTPUT = defaultdict(lambda: 64) 57 | OUTPUT.update({MT19937: 32, DSFMT: 32}) 58 | with open("templates/configuration.jinja") as tmpl: 59 | TEMPLATE = jinja2.Template(tmpl.read()) 60 | 61 | DSFMT_WRAPPER = """\ 62 | 63 | class Wrapper32: 64 | def __init__(self, seed, **kwargs): 65 | if isinstance(seed, rg.DSFMT): 66 | self._bit_gen = seed 67 | else: 68 | self._bit_gen = rg.DSFMT(seed) 69 | 70 | def random_raw(self, n=None): 71 | return self._bit_gen.random_raw(n).astype("u4") 72 | 73 | def jumped(self): 74 | return Wrapper32(self._bit_gen.jumped()) 75 | 76 | rg.Wrapper32 = Wrapper32 77 | """ 78 | # Specials 79 | # SFC64 80 | DEFAULT_ENTOPY = ( 81 | 86316980830225721106033794313786972513572058861498566720023788662568817403978 82 | ) 83 | -------------------------------------------------------------------------------- /tools/long_double_sizes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A simple file that can be used to read long double sizes on different 3 | * platforms 4 | */ 5 | #include 6 | #include 7 | 8 | int main(){ 9 | printf("Mantissa: %d, ", LDBL_MANT_DIG+0); 10 | printf("Exponent %d\n", LDBL_MAX_EXP+0); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tools/practrand-driver-config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | This file contains an exampls of a configuration file 4 | that can be used by practrand-driver. 5 | 6 | Typical usage: 7 | 8 | python practrand-driver.py -if practrand-driver-config.py | \ 9 | ./RNG_test stdin64 -tlmax 1TB -multithreaded 10 | """ 11 | import numpy as np 12 | 13 | import randomgen as rg 14 | 15 | ENTROPY = 86316980830225721106033794313786972513572058861498566720023788662568817403978 16 | ss = rg.SeedSequence(ENTROPY >> 128) 17 | bg = rg.SFC64(ss) 18 | 19 | seen = set() 20 | remaining = NUM = 8192 21 | while remaining: 22 | vals = bg.random_raw(remaining) | np.uint64(0x1) 23 | seen.update(vals.tolist()) 24 | remaining = NUM - len(seen) 25 | 26 | bitgens = [] 27 | for k in seen: 28 | bitgens.append(rg.SFC64(rg.SeedSequence(ENTROPY), k=k)) 29 | output = 64 30 | -------------------------------------------------------------------------------- /tools/templates/configuration.jinja: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import randomgen as rg 3 | 4 | ENTROPY = {{ entropy }} 5 | JUMPED = {{ jumped }} 6 | STREAMS = {{ streams }} 7 | BIT_GENERATOR_KWARGS = {{ kwargs }} 8 | 9 | SEED_SEQ = np.random.SeedSequence(ENTROPY) 10 | 11 | {{ extra_initialization }} 12 | BASE_GEN = rg.{{ bit_generator }}(SEED_SEQ, **BIT_GENERATOR_KWARGS) 13 | if STREAMS == 1: 14 | bitgens = [BASE_GEN] 15 | elif JUMPED: 16 | bitgens = [BASE_GEN] 17 | for _ in range(STREAMS - 1): 18 | bitgens.append(bitgens[-1].jumped()) 19 | else: 20 | bitgens = [] 21 | for child in SEED_SEQ.spawn(STREAMS): 22 | bitgens.append(rg.{{ bit_generator }}(child, **BIT_GENERATOR_KWARGS)) 23 | output = {{ output }} 24 | 25 | {{ extra_code }} 26 | -------------------------------------------------------------------------------- /tools/templates/seed-correlation.jinja: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | import randomgen as rg 4 | 5 | STREAMS = {{ streams }} 6 | BIT_GENERATOR_KWARGS = {{ kwargs }} 7 | SEQUENTIAL = {{ sequential }} 8 | 9 | {{ extra_initialization }} 10 | 11 | bitgens = [] 12 | for i in range(STREAMS): 13 | if SEQUENTIAL: 14 | seed_seq = np.random.SeedSequence(i) 15 | else: 16 | seed_seq = np.random.SeedSequence(2**i) 17 | bitgens.append(rg.{{ bit_generator }}(seed_seq, **BIT_GENERATOR_KWARGS)) 18 | output = {{ output }} 19 | 20 | {{ extra_code }} 21 | --------------------------------------------------------------------------------