Git Product home page Git Product logo

bitgenerators's Introduction

bitgenerators

codecov CI license

This library provides a port of numpy's random module bitgenerator interface for working with pseudo-random number generation. Several PRNG algorithms are implemented and exposed using numpy's bitgenerator interface in a purely functional manner for Ocaml users.

Documentation

Comprehensive documentation of available features is available at the project's site.

Installation

The library can be installed using opam with the following commands:

opam update
opam install bitgenerators

Alternatively, one can install the development version using the latest git commit:

opam pin add bitgenerators git+https://github.com/zoj613/bitgenerators

Usage

A SeedSequence module based on these ideas is available to providing a high quality seed sequence that can be used to initialize any of the supported PRNG's:

open Bitgen
open Stdint

let seedseq = SeedSequence.initialize [Uint128.of_int 123456789]
let rng = PCG64.initialize seedseq 

It can also be used to initialize any custom PRNG using the module's generate_64bit_state and generate_32bit_state functions:

SeedSequence.generate_64bit_state 4 seedseq |> Array.map Uint64.to_string 
(* - : string array =
   [|"5976902797103608158"; "11230215241436205182"; "1766494744865860250";
     "7661475472903581292"|] *)

Below is an example of using an initialized PCG64 bitgenerator to generate 10 random floats:

let rec compute t acc = function
    | 0 -> List.rev acc, t
    | i -> let u, t' = PCG64.next_uint64 t in compute t' (Uint64.to_string u :: acc) (i - 1)
in compute rng [] 10 |> fst
(* - : string list =
   ["511209809126027580"; "16725663875132018381"; "16258841331763118777";
    "11527320112047894150"; "14586113755615299794"; "15235313769381631730";
    "15526732141789886995"; "8701844723981253752"; "17657754321871037678";
    "17461531751233692673"] *)

One can use SeedSequence.spawn to generate many independent bitgenerators that can be used in parallel computations in a reproducible manner:

let next_float t = Some (PCG64.next_double t) in
let compute t = Seq.unfold next_float t |> Seq.take 6 |> List.of_seq in
SeedSequence.spawn 4 seedseq
|> fst
|> List.map PCG64.initialize
|> List.map (fun x -> Domain.spawn (fun () -> compute x))
|> List.map Domain.join
(* - : float list list =
[[0.407206833679825242; 0.189731803785485376; 0.564081542309661343;
  0.88682304196963746; 0.45229844727129942; 0.701372920128140565];
 [0.580212874721654503; 0.0892784737148068; 0.511665172650789257;
  0.931271866226736411; 0.928633846357239; 0.173606152636579414];
 [0.171815817392286574; 0.585509477690361213; 0.837844400599859318;
  0.569340928519763145; 0.680737776645169879; 0.620841051213270267];
 [0.736203907003532887; 0.479879743687943505; 0.506036578793879;
  0.596207202439843376; 0.792829648424435; 0.540970530700028429]] *)

Another pattern to generate independent non-overlapping instances of a bitgenerator for parallel applications is to use jump or advance functions for PRNG's that support such functions:

Philox4x64.initialize seedseq |> Seq.iterate Philox4x64.jump |> Seq.take 5 |> List.of_seq 
(* - : Philox4x64.t list = [<abstr>; <abstr>; <abstr>; <abstr>; <abstr>] *)

The resulting list of bitgenerators produce non-overlapping streams of random numbers.

Supported bitgenerators include: PCG64, Philox4x64, Xoshiro256, ChaCha, SFC64, LXM and EFIIX64x48. More coming soon!

Empirical Randomness Testing

Running the test suite provided by TestU01 on the supported generators is supported. To see the available commandline options run dune exec -- ./bin/crush.exe -help. Below is a sample output from running dune exec -- ./bin/crush.exe -name smallcrush pcg64 to test PCG64 on the Small Crush test suite:

========= Summary results of SmallCrush =========

 Version:          TestU01 1.2.3
 Generator:        pcg64
 Number of statistics:  15
 Total CPU time:   00:01:40.64

 All tests were passed

Benchmarks

A utility to compare the performance of each bitgenerator's next_uint64 function is provided. Run the microbenchmark using dune exec -- ./bin/bench.exe and once it has completed, a summary table will be displayed in stdout.

bitgenerators's People

Contributors

zoj613 avatar

Stargazers

Brandon T. Willard avatar

Watchers

 avatar  avatar

Forkers

prgbln

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.