randomkit/lib.rs
1//! Nonuniform pseudorandom number generation
2//!
3//! This library provides a suite of nonuniform random number generators
4//! via bindings to the Numpy fork of RandomKit. It is approximately
5//! equivalent to Numpy's `numpy.random` module. The API is loosely
6//! based on that of the [`rand`](https://github.com/rust-lang/rand)
7//! crate.
8//!
9//! This library is not suitable for cryptography.
10//!
11//! # Usage
12//!
13//! Add this to your `Cargo.toml`:
14//!
15//! ```toml
16//! [dependencies]
17//! randomkit = "0.1"
18//! ```
19//!
20//! and this to your crate root:
21//!
22//! ```rust
23//! extern crate randomkit;
24//! ```
25//!
26//! # Examples
27//!
28//! ## Standard normal distribution
29//!
30//! Sample 1000 numbers from the standard normal distribution (Gauss
31//! distribution) with mean 0 and standard deviation 1.
32//!
33//! ```rust
34//! extern crate randomkit;
35//!
36//! use randomkit::{Rng, Sample};
37//! use randomkit::dist::Gauss;
38//!
39//! fn main() {
40//! let mut rng = Rng::new().unwrap();
41//! for _ in 0..1000 {
42//! println!("{}", Gauss.sample(&mut rng));
43//! }
44//! }
45//! ```
46//!
47//! ## Normal distribution
48//!
49//! Sample 1000 numbers from a normal distribution with mean 10 and
50//! standard deviation 5.
51//!
52//! ```rust
53//! extern crate randomkit;
54//!
55//! use randomkit::{Rng, Sample};
56//! use randomkit::dist::Normal;
57//!
58//! fn main() {
59//! let mut rng = Rng::from_seed(1);
60//! let normal = Normal::new(10.0, 5.0).unwrap();
61//! for _ in 0..1000 {
62//! println!("{}", normal.sample(&mut rng));
63//! }
64//! }
65//! ```
66
67#![crate_name = "randomkit"]
68
69extern crate libc;
70
71use std::mem;
72use libc::c_ulong;
73
74pub mod dist;
75mod ffi;
76
77pub struct Rng { state: ffi::RkState }
78
79impl Rng {
80 unsafe fn uninitialized() -> Rng {
81 Rng { state: mem::uninitialized() }
82 }
83
84 /// Initialize a new pseudorandom number generator from a seed.
85 pub fn from_seed(seed: u32) -> Rng {
86 // Seed is &'d with 0xffffffff in randomkit.c, so there's no
87 // point in making it larger.
88 unsafe {
89 let mut r = Rng::uninitialized();
90 ffi::rk_seed(seed as c_ulong, &mut r.state);
91 r
92 }
93 }
94
95 /// Initialize a new pseudorandom number generator using the
96 /// operating system's random number generator as the seed.
97 pub fn new() -> Option<Rng> {
98 unsafe {
99 let mut r = Rng::uninitialized();
100 match ffi::rk_randomseed(&mut r.state) {
101 ffi::RkError::RkNoerr => Some(r),
102 _ => None,
103 }
104 }
105 }
106}
107
108pub trait Sample<Support> {
109 /// Generate a pseudorandom element of `Support` using `rng` as the
110 /// source of randomness.
111 fn sample(&self, rng: &mut Rng) -> Support;
112}