diff options
| author | Jonas Hietala <tradet.h@gmail.com> | 2014-07-28 17:52:48 +0200 |
|---|---|---|
| committer | Jonas Hietala <tradet.h@gmail.com> | 2014-07-28 17:52:48 +0200 |
| commit | 23b84e55e4dc0ed35192070cd442a0f5fd38a87e (patch) | |
| tree | 789746c57eed20cb50dd6d89e41d68e87323426d /src/libstd | |
| parent | 42ca8a70d60d066367484b153c1d84de728b14cf (diff) | |
| download | rust-23b84e55e4dc0ed35192070cd442a0f5fd38a87e.tar.gz rust-23b84e55e4dc0ed35192070cd442a0f5fd38a87e.zip | |
doc: use //! instead of /*! ... */ in std::rand
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/rand/mod.rs | 330 |
1 files changed, 163 insertions, 167 deletions
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index 013640dba5d..40d8f80171c 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -8,173 +8,169 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! - -Utilities for random number generation - -The key functions are `random()` and `Rng::gen()`. These are polymorphic -and so can be used to generate any type that implements `Rand`. Type inference -means that often a simple call to `rand::random()` or `rng.gen()` will -suffice, but sometimes an annotation is required, e.g. `rand::random::<f64>()`. - -See the `distributions` submodule for sampling random numbers from -distributions like normal and exponential. - -# Task-local RNG - -There is built-in support for a RNG associated with each task stored -in task-local storage. This RNG can be accessed via `task_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. - -# Cryptographic security - -An application that requires an entropy source for cryptographic purposes -must use `OsRng`, which reads randomness from the source that the operating -system provides (e.g. `/dev/urandom` on Unixes or `CryptGenRandom()` on Windows). -The other random number generators provided by this module are not suitable -for such purposes. - -*Note*: many Unix systems provide `/dev/random` as well as `/dev/urandom`. -This module uses `/dev/urandom` for the following reasons: - -- On Linux, `/dev/random` may block if entropy pool is empty; `/dev/urandom` will not block. - This does not mean that `/dev/random` provides better output than - `/dev/urandom`; the kernel internally runs a cryptographically secure pseudorandom - number generator (CSPRNG) based on entropy pool for random number generation, - so the "quality" of `/dev/random` is not better than `/dev/urandom` in most cases. - However, this means that `/dev/urandom` can yield somewhat predictable randomness - if the entropy pool is very small, such as immediately after first booting. - If an application likely to be run soon after first booting, or on a system with very - few entropy sources, one should consider using `/dev/random` via `ReaderRng`. -- On some systems (e.g. FreeBSD, OpenBSD and Mac OS X) there is no difference - between the two sources. (Also note that, on some systems e.g. FreeBSD, both `/dev/random` - and `/dev/urandom` may block once if the CSPRNG has not seeded yet.) - -# Examples - -```rust -use std::rand; -use std::rand::Rng; - -let mut rng = rand::task_rng(); -if rng.gen() { // random bool - println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>()) -} -``` - -```rust -use std::rand; - -let tuple = rand::random::<(f64, char)>(); -println!("{}", tuple) -``` - -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 of 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]: http://en.wikipedia.org/wiki/Monty_Hall_problem - -``` -use std::rand; -use std::rand::Rng; -use std::rand::distributions::{IndependentSample, Range}; - -struct SimulationResult { - win: bool, - switch: bool, -} - -// Run a single simulation of the Monty Hall problem. -fn simulate<R: Rng>(random_door: &Range<uint>, rng: &mut R) -> SimulationResult { - let car = random_door.ind_sample(rng); - - // This is our initial choice - let mut choice = random_door.ind_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: uint, choice: uint, rng: &mut R) -> uint { - let choices = free_doors(&[car, choice]); - rand::sample(rng, choices.move_iter(), 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: uint, open: uint) -> uint { - free_doors(&[choice, open])[0] -} - -fn free_doors(blocked: &[uint]) -> Vec<uint> { - range(0u, 3).filter(|x| !blocked.contains(x)).collect() -} - -fn main() { - // The estimation will be more accurate with more simulations - let num_simulations = 10000u; - - let mut rng = rand::task_rng(); - let random_door = Range::new(0u, 3); - - let (mut switch_wins, mut switch_losses) = (0u, 0u); - let (mut keep_wins, mut keep_losses) = (0u, 0u); - - println!("Running {} simulations...", num_simulations); - for _ in range(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); -} -``` - -*/ +//! Utilities for random number generation +//! +//! The key functions are `random()` and `Rng::gen()`. These are polymorphic +//! and so can be used to generate any type that implements `Rand`. Type inference +//! means that often a simple call to `rand::random()` or `rng.gen()` will +//! suffice, but sometimes an annotation is required, e.g. `rand::random::<f64>()`. +//! +//! See the `distributions` submodule for sampling random numbers from +//! distributions like normal and exponential. +//! +//! # Task-local RNG +//! +//! There is built-in support for a RNG associated with each task stored +//! in task-local storage. This RNG can be accessed via `task_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. +//! +//! # Cryptographic security +//! +//! An application that requires an entropy source for cryptographic purposes +//! must use `OsRng`, which reads randomness from the source that the operating +//! system provides (e.g. `/dev/urandom` on Unixes or `CryptGenRandom()` on Windows). +//! The other random number generators provided by this module are not suitable +//! for such purposes. +//! +//! *Note*: many Unix systems provide `/dev/random` as well as `/dev/urandom`. +//! This module uses `/dev/urandom` for the following reasons: +//! +//! - On Linux, `/dev/random` may block if entropy pool is empty; `/dev/urandom` will not block. +//! This does not mean that `/dev/random` provides better output than +//! `/dev/urandom`; the kernel internally runs a cryptographically secure pseudorandom +//! number generator (CSPRNG) based on entropy pool for random number generation, +//! so the "quality" of `/dev/random` is not better than `/dev/urandom` in most cases. +//! However, this means that `/dev/urandom` can yield somewhat predictable randomness +//! if the entropy pool is very small, such as immediately after first booting. +//! If an application likely to be run soon after first booting, or on a system with very +//! few entropy sources, one should consider using `/dev/random` via `ReaderRng`. +//! - On some systems (e.g. FreeBSD, OpenBSD and Mac OS X) there is no difference +//! between the two sources. (Also note that, on some systems e.g. FreeBSD, both `/dev/random` +//! and `/dev/urandom` may block once if the CSPRNG has not seeded yet.) +//! +//! # Examples +//! +//! ```rust +//! use std::rand; +//! use std::rand::Rng; +//! +//! let mut rng = rand::task_rng(); +//! if rng.gen() { // random bool +//! println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>()) +//! } +//! ``` +//! +//! ```rust +//! use std::rand; +//! +//! let tuple = rand::random::<(f64, char)>(); +//! println!("{}", tuple) +//! ``` +//! +//! 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 of 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]: http://en.wikipedia.org/wiki/Monty_Hall_problem +//! +//! ``` +//! use std::rand; +//! use std::rand::Rng; +//! use std::rand::distributions::{IndependentSample, Range}; +//! +//! struct SimulationResult { +//! win: bool, +//! switch: bool, +//! } +//! +//! // Run a single simulation of the Monty Hall problem. +//! fn simulate<R: Rng>(random_door: &Range<uint>, rng: &mut R) -> SimulationResult { +//! let car = random_door.ind_sample(rng); +//! +//! // This is our initial choice +//! let mut choice = random_door.ind_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: uint, choice: uint, rng: &mut R) -> uint { +//! let choices = free_doors(&[car, choice]); +//! rand::sample(rng, choices.move_iter(), 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: uint, open: uint) -> uint { +//! free_doors(&[choice, open])[0] +//! } +//! +//! fn free_doors(blocked: &[uint]) -> Vec<uint> { +//! range(0u, 3).filter(|x| !blocked.contains(x)).collect() +//! } +//! +//! fn main() { +//! // The estimation will be more accurate with more simulations +//! let num_simulations = 10000u; +//! +//! let mut rng = rand::task_rng(); +//! let random_door = Range::new(0u, 3); +//! +//! let (mut switch_wins, mut switch_losses) = (0u, 0u); +//! let (mut keep_wins, mut keep_losses) = (0u, 0u); +//! +//! println!("Running {} simulations...", num_simulations); +//! for _ in range(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); +//! } +//! ``` #![experimental] |
