Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ matrix:
- cargo test --all --features=alloc
- cargo test --features serde-1,log,nightly
- cargo test --benches
- cargo doc --no-deps --all-features
- cargo doc --no-deps --all --all-features
after_success:
- travis-cargo --only nightly doc-upload

Expand Down
57 changes: 32 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,34 @@ Rand

A Rust library for random number generators and other randomness functionality.

See also:

* [rand_core](https://crates.io/crates/rand_core)

[![Build Status](https://travis-ci.org/rust-lang-nursery/rand.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/rand)
[![Build status](https://ci.appveyor.com/api/projects/status/rm5c9o33k3jhchbw?svg=true)](https://ci.appveyor.com/project/alexcrichton/rand)

[Documentation](https://docs.rs/rand)
Documentation:
[master branch](https://rust-lang-nursery.github.io/rand/rand/index.html),
[by release](https://docs.rs/rand)

## Usage

Add this to your `Cargo.toml`:

```toml
[dependencies]
rand = "0.4"
rand = "0.5.0-pre.0"
```

and this to your crate root:

```rust
extern crate rand;

// example usage:
use rand::{Rng, thread_rng};
let x: f64 = thread_rng().gen();
```

## Versions
Expand All @@ -44,34 +54,31 @@ Travis CI always has a build with a pinned version of Rustc matching the oldest
supported Rust release. The current policy is that this can be updated in any
Rand release if required, but the change must be noted in the changelog.

## Examples

There is built-in support for a random number generator (RNG) associated with each thread stored in thread-local storage. This RNG can be accessed via thread_rng, or used implicitly via random. This RNG is normally randomly seeded from an operating-system source of randomness, e.g. /dev/urandom on Unix systems, and will automatically reseed itself from this source after generating 32 KiB of random data.

```rust
let tuple = rand::random::<(f64, char)>();
println!("{:?}", tuple)
```

```rust
use rand::Rng;
## Functionality

let mut rng = rand::thread_rng();
if rng.gen() { // random bool
println!("i32: {}, u32: {}", rng.gen::<i32>(), rng.gen::<u32>())
}
```
The `rand_core` crate provides:

It is also possible to use other RNG types, which have a similar interface. The following uses the "ChaCha" algorithm instead of the default.
- base random number generator traits
- error-reporting types
- functionality to aid implementation of RNGs

```rust
use rand::{Rng, ChaChaRng};
The `rand` crate provides:

let mut rng = rand::ChaChaRng::new_unseeded();
println!("i32: {}, u32: {}", rng.gen::<i32>(), rng.gen::<u32>())
```
- most content from `rand_core` (re-exported)
- fresh entropy: `EntropyRng`, `OsRng`, `JitterRng`
- pseudo-random number generators: `StdRng`, `SmallRng`, `prng` module
- convenient, auto-seeded crypto-grade thread-local generator: `thread_rng`
- `distributions` producing many different types of random values:
- `Uniform`-ly distributed integers and floats of many types
- unbiased sampling from specified `Range`s
- sampling from exponential/normal/gamma distributions
- sampling from binomial/poisson distributions
- `gen_bool` aka Bernoulli distribution
- `seq`-uence related functionality:
- sampling a subset of elements
- randomly shuffling a list

## Features
## Crate Features

By default, Rand is built with all stable features available. The following
optional features are available:
Expand Down
52 changes: 52 additions & 0 deletions examples/monte-carlo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2013-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # Monte Carlo estimation of π
//!
//! Imagine that we have a square with sides of length 2 and a unit circle
//! (radius = 1), both centered at the origin. The areas are:
//!
//! ```text
//! area of circle = πr² = π * r * r = π
//! area of square = 2² = 4
//! ```
//!
//! The circle is entirely within the square, so if we sample many points
//! randomly from the square, roughly π / 4 of them should be inside the circle.
//!
//! We can use the above fact to estimate the value of π: pick many points in
//! the square at random, calculate the fraction that fall within the circle,
//! and multiply this fraction by 4.

#![cfg(feature="std")]


extern crate rand;

use rand::distributions::{Distribution, Range};

fn main() {
let range = Range::new(-1.0f64, 1.0);
let mut rng = rand::thread_rng();

let total = 1_000_000;
let mut in_circle = 0;

for _ in 0..total {
let a = range.sample(&mut rng);
let b = range.sample(&mut rng);
if a*a + b*b <= 1.0 {
in_circle += 1;
}
}

// prints something close to 3.14159...
println!("π is approximately {}", 4. * (in_circle as f64) / (total as f64));
}
118 changes: 118 additions & 0 deletions examples/monty-hall.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright 2013-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! ## Monty Hall Problem
//!
//! This is a simulation of the [Monty Hall Problem][]:
//!
//! > Suppose you're on a game show, and you're given the choice of three doors:
//! > Behind one door is a car; behind the others, goats. You pick a door, say
//! > No. 1, and the host, who knows what's behind the doors, opens another
//! > door, say No. 3, which has a goat. He then says to you, "Do you want to
//! > pick door No. 2?" Is it to your advantage to switch your choice?
//!
//! The rather unintuitive answer is that you will have a 2/3 chance of winning
//! if you switch and a 1/3 chance of winning if you don't, so it's better to
//! switch.
//!
//! This program will simulate the game show and with large enough simulation
//! steps it will indeed confirm that it is better to switch.
//!
//! [Monty Hall Problem]: https://en.wikipedia.org/wiki/Monty_Hall_problem

#![cfg(feature="std")]


extern crate rand;

use rand::Rng;
use rand::distributions::{Distribution, Range};
use rand::distributions::range::RangeInt;

struct SimulationResult {
win: bool,
switch: bool,
}

// Run a single simulation of the Monty Hall problem.
fn simulate<R: Rng>(random_door: &Range<RangeInt<u32>>, rng: &mut R)
-> SimulationResult {
let car = random_door.sample(rng);

// This is our initial choice
let mut choice = random_door.sample(rng);

// The game host opens a door
let open = game_host_open(car, choice, rng);

// Shall we switch?
let switch = rng.gen();
if switch {
choice = switch_door(choice, open);
}

SimulationResult { win: choice == car, switch: switch }
}

// Returns the door the game host opens given our choice and knowledge of
// where the car is. The game host will never open the door with the car.
fn game_host_open<R: Rng>(car: u32, choice: u32, rng: &mut R) -> u32 {
let choices = free_doors(&[car, choice]);
rand::seq::sample_slice(rng, &choices, 1)[0]
}

// Returns the door we switch to, given our current choice and
// the open door. There will only be one valid door.
fn switch_door(choice: u32, open: u32) -> u32 {
free_doors(&[choice, open])[0]
}

fn free_doors(blocked: &[u32]) -> Vec<u32> {
(0..3).filter(|x| !blocked.contains(x)).collect()
}

fn main() {
// The estimation will be more accurate with more simulations
let num_simulations = 10000;

let mut rng = rand::thread_rng();
let random_door = Range::new(0u32, 3);

let (mut switch_wins, mut switch_losses) = (0, 0);
let (mut keep_wins, mut keep_losses) = (0, 0);

println!("Running {} simulations...", num_simulations);
for _ in 0..num_simulations {
let result = simulate(&random_door, &mut rng);

match (result.win, result.switch) {
(true, true) => switch_wins += 1,
(true, false) => keep_wins += 1,
(false, true) => switch_losses += 1,
(false, false) => keep_losses += 1,
}
}

let total_switches = switch_wins + switch_losses;
let total_keeps = keep_wins + keep_losses;

println!("Switched door {} times with {} wins and {} losses",
total_switches, switch_wins, switch_losses);

println!("Kept our choice {} times with {} wins and {} losses",
total_keeps, keep_wins, keep_losses);

// With a large number of simulations, the values should converge to
// 0.667 and 0.333 respectively.
println!("Estimated chance to win if we switch: {}",
switch_wins as f32 / total_switches as f32);
println!("Estimated chance to win if we don't: {}",
keep_wins as f32 / total_keeps as f32);
}
24 changes: 23 additions & 1 deletion rand_core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,29 @@ prefer to use the main [rand] crate.

[Documentation](https://docs.rs/rand_core)

[rand]: ../README.md
[rand]: https://crates.io/crates/rand


## Functionality

The `rand_core` crate provides:

- base random number generator traits
- error-reporting types
- functionality to aid implementation of RNGs

The traits and error types are also available via `rand`.

## Crate Features

`rand_core` supports `no_std` and `alloc`-only configurations, as well as full
`std` functionality. The differences between `no_std` and full `std` are small,
comprising `RngCore` support for `Box<R>` types where `R: RngCore`, as well as
extensions to the `Error` type's functionality.

Due to a bug in Cargo, `rand_core` is built without `std` support by default.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds a bit negative. Can you say "Due to {issue-number}"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was intended to be, and it's documented in Cargo.toml.

Maybe some day Cargo will have a lot less rough edges. I guess a flexible build/packaging tool turned out to be a considerably more complex than was initially envisaged. For now it still feels like a quick hack in many ways.

Since features are unioned across the whole dependency tree, any crate using
`rand` with its default features will also enable `std` support in `rand_core`.


# License
Expand Down
Loading