diff --git a/rand_chacha/src/chacha.rs b/rand_chacha/src/chacha.rs
index a7a28b227e8..a4c9552a909 100644
--- a/rand_chacha/src/chacha.rs
+++ b/rand_chacha/src/chacha.rs
@@ -114,7 +114,7 @@ macro_rules! chacha_impl {
/// except that we use a stream identifier in place of a nonce. A 64-bit counter over 64-byte
/// (16 word) blocks allows 1 ZiB of output before cycling, and the stream identifier allows
/// 264 unique streams of output per seed. Both counter and stream are initialized
- /// to zero but may be set via [`set_word_pos`] and [`set_stream`].
+ /// to zero but may be set via the `set_word_pos` and `set_stream` methods.
///
/// The word layout is:
///
@@ -133,9 +133,6 @@ macro_rules! chacha_impl {
///
/// [^2]: [eSTREAM: the ECRYPT Stream Cipher Project](
/// http://www.ecrypt.eu.org/stream/)
- ///
- /// [`set_word_pos`]: ChaChaXRng::set_word_pos
- /// [`set_stream`]: ChaChaXRng::set_stream
#[derive(Clone, Debug)]
pub struct $ChaChaXRng {
rng: BlockRng<$ChaChaXCore>,
diff --git a/rand_distr/src/pert.rs b/rand_distr/src/pert.rs
index 509d05af139..040cd05cfed 100644
--- a/rand_distr/src/pert.rs
+++ b/rand_distr/src/pert.rs
@@ -13,9 +13,9 @@ use crate::utils::Float;
/// The PERT distribution.
///
-/// Similar to the [Triangular] distribution, the PERT distribution is
+/// Similar to the [`Triangular`] distribution, the PERT distribution is
/// parameterised by a range and a mode within that range. Unlike the
-/// [Triangular] distribution, the probability density function of the PERT
+/// [`Triangular`] distribution, the probability density function of the PERT
/// distribution is smooth, with a configurable weighting around the mode.
///
/// # Example
@@ -27,6 +27,8 @@ use crate::utils::Float;
/// let v = d.sample(&mut rand::thread_rng());
/// println!("{} is from a PERT distribution", v);
/// ```
+///
+/// [`Triangular`]: crate::Triangular
#[derive(Clone, Copy, Debug)]
pub struct Pert {
min: N,
diff --git a/rand_distr/src/triangular.rs b/rand_distr/src/triangular.rs
index a793669ad40..dd0bbfbdf29 100644
--- a/rand_distr/src/triangular.rs
+++ b/rand_distr/src/triangular.rs
@@ -17,7 +17,7 @@ use crate::utils::Float;
/// (most likely value) within that range.
///
/// The probability density function is triangular. For a similar distribution
-/// with a smooth PDF, see the [Pert] distribution.
+/// with a smooth PDF, see the [`Pert`] distribution.
///
/// # Example
///
@@ -28,6 +28,8 @@ use crate::utils::Float;
/// let v = d.sample(&mut rand::thread_rng());
/// println!("{} is from a triangular distribution", v);
/// ```
+///
+/// [`Pert`]: crate::Pert
#[derive(Clone, Copy, Debug)]
pub struct Triangular {
min: N,
diff --git a/src/distributions/weighted/mod.rs b/src/distributions/weighted/mod.rs
index de2711b1527..5c2cd97c21f 100644
--- a/src/distributions/weighted/mod.rs
+++ b/src/distributions/weighted/mod.rs
@@ -6,8 +6,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! This module contains different algorithms for sampling random indices with
-//! probabilities proportional to a collection of weights.
+//! Weighted index sampling
+//!
+//! This module provides two implementations for sampling indices:
+//!
+//! * [`WeightedIndex`] allows `O(log N)` sampling
+//! * [`alias_method::WeightedIndex`] allows `O(1)` sampling, but with
+//! much greater set-up cost
+//!
+//! [`alias_method::WeightedIndex`]: alias_method/struct.WeightedIndex.html
pub mod alias_method;
diff --git a/src/rngs/adapter/read.rs b/src/rngs/adapter/read.rs
index 77b2a16d055..c64230f3059 100644
--- a/src/rngs/adapter/read.rs
+++ b/src/rngs/adapter/read.rs
@@ -41,7 +41,7 @@ use rand_core::{RngCore, Error, impls};
/// println!("{:x}", rng.gen::());
/// ```
///
-/// [`OsRng`]: rngs::OsRng
+/// [`OsRng`]: crate::rngs::OsRng
/// [`try_fill_bytes`]: RngCore::try_fill_bytes
#[derive(Debug)]
pub struct ReadRng {
diff --git a/src/rngs/adapter/reseeding.rs b/src/rngs/adapter/reseeding.rs
index 57c6c7503dd..b05c05247e9 100644
--- a/src/rngs/adapter/reseeding.rs
+++ b/src/rngs/adapter/reseeding.rs
@@ -72,7 +72,6 @@ use rand_core::block::{BlockRngCore, BlockRng};
/// assert!(reseeding_rng.gen::() != cloned_rng.gen::());
/// ```
///
-/// [`ChaCha20Core`]: ../../../rand_chacha/struct.ChaCha20Core.html
/// [`BlockRngCore`]: rand_core::block::BlockRngCore
/// [`ReseedingRng::new`]: ReseedingRng::new
/// [`reseed()`]: ReseedingRng::reseed
diff --git a/src/rngs/entropy.rs b/src/rngs/entropy.rs
index fdcc3be52c6..cfb6490fbfe 100644
--- a/src/rngs/entropy.rs
+++ b/src/rngs/entropy.rs
@@ -18,6 +18,8 @@ use crate::rngs::OsRng;
/// specifically for securely seeding algorithmic generators (PRNGs).
///
/// This is deprecated. It is suggested you use [`rngs::OsRng`] instead.
+///
+/// [`rngs::OsRng`]: crate::rngs::OsRng
#[derive(Debug)]
#[deprecated(since="0.7.0", note="use rngs::OsRng instead")]
pub struct EntropyRng {
diff --git a/src/rngs/mod.rs b/src/rngs/mod.rs
index a9a03401c65..6d337e260e6 100644
--- a/src/rngs/mod.rs
+++ b/src/rngs/mod.rs
@@ -91,7 +91,6 @@
//! [`mock::StepRng`]: rngs::mock::StepRng
//! [`adapter::ReadRng`]: rngs::adapter::ReadRng
//! [`adapter::ReseedingRng`]: rngs::adapter::ReseedingRng
-//! [`ChaCha20Rng`]: ../../rand_chacha/struct.ChaCha20Rng.html
//! [`rdrand`]: https://crates.io/crates/rdrand
//! [`rand_jitter`]: https://crates.io/crates/rand_jitter
//! [`rand_chacha`]: https://crates.io/crates/rand_chacha
diff --git a/src/seq/index.rs b/src/seq/index.rs
index d524329e31f..0c9a477f24f 100644
--- a/src/seq/index.rs
+++ b/src/seq/index.rs
@@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Index sampling
+//! Low-level API for sampling indices
#[cfg(feature="alloc")] use core::slice;
diff --git a/src/seq/mod.rs b/src/seq/mod.rs
index 0ad0474b5f8..1f3d103d495 100644
--- a/src/seq/mod.rs
+++ b/src/seq/mod.rs
@@ -6,9 +6,23 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Functions for randomly accessing and sampling sequences.
+//! Sequence-related functionality
//!
-//! TODO: module doc
+//! This module provides:
+//!
+//! * [`seq::SliceRandom`] slice sampling and mutation
+//! * [`seq::IteratorRandom`] iterator sampling
+//! * [`seq::index::sample`] low-level API to choose multiple indices from
+//! `0..length`
+//!
+//! Also see:
+//!
+//! * [`distributions::weighted`] module which provides implementations of
+//! weighted index sampling.
+//!
+//! In order to make results reproducible across 32-64 bit architectures, all
+//! `usize` indices are sampled as a `u32` where possible (also providing a
+//! small performance boost in some cases).
#[cfg(feature="alloc")] pub mod index;
@@ -23,8 +37,24 @@ use crate::Rng;
/// Extension trait on slices, providing random mutation and sampling methods.
///
-/// An implementation is provided for slices. This may also be implementable for
-/// other types.
+/// This trait is implemented on all `[T]` slice types, providing several
+/// methods for choosing and shuffling elements. You must `use` this trait:
+///
+/// ```
+/// use rand::seq::SliceRandom;
+///
+/// fn main() {
+/// let mut rng = rand::thread_rng();
+/// let mut bytes = "Hello, random!".to_string().into_bytes();
+/// bytes.shuffle(&mut rng);
+/// let str = String::from_utf8(bytes).unwrap();
+/// println!("{}", str);
+/// }
+/// ```
+/// Example output (non-deterministic):
+/// ```none
+/// l,nmroHado !le
+/// ```
pub trait SliceRandom {
/// The element type.
type Item;
@@ -32,7 +62,7 @@ pub trait SliceRandom {
/// Returns a reference to one random element of the slice, or `None` if the
/// slice is empty.
///
- /// Depending on the implementation, complexity is expected to be `O(1)`.
+ /// For slices, complexity is `O(1)`.
///
/// # Example
///
@@ -51,17 +81,17 @@ pub trait SliceRandom {
/// Returns a mutable reference to one random element of the slice, or
/// `None` if the slice is empty.
///
- /// Depending on the implementation, complexity is expected to be `O(1)`.
+ /// For slices, complexity is `O(1)`.
fn choose_mut(&mut self, rng: &mut R) -> Option<&mut Self::Item>
where R: Rng + ?Sized;
- /// Produces an iterator that chooses `amount` elements from the slice at
- /// random without repeating any, and returns them in random order.
+ /// Chooses `amount` elements from the slice at random, without repetition,
+ /// and in random order. The returned iterator is appropriate both for
+ /// collection into a `Vec` and filling an existing buffer (see example).
///
- /// In case this API is not sufficiently flexible, use `index::sample` then
- /// apply the indices to the slice.
+ /// In case this API is not sufficiently flexible, use [`index::sample`].
///
- /// Complexity is expected to be the same as `index::sample`.
+ /// For slices, complexity is the same as [`index::sample`].
///
/// # Example
/// ```
@@ -83,11 +113,16 @@ pub trait SliceRandom {
fn choose_multiple(&self, rng: &mut R, amount: usize) -> SliceChooseIter
where R: Rng + ?Sized;
- /// Similar to [`choose`], where the likelihood of each outcome may be
- /// specified. The specified function `weight` maps items `x` to a relative
+ /// Similar to [`choose`], but where the likelihood of each outcome may be
+ /// specified.
+ ///
+ /// The specified function `weight` maps each item `x` to a relative
/// likelihood `weight(x)`. The probability of each item being selected is
/// therefore `weight(x) / s`, where `s` is the sum of all `weight(x)`.
///
+ /// For slices of length `n`, complexity is `O(n)`.
+ /// See also [`choose_weighted_mut`], [`distributions::weighted`].
+ ///
/// # Example
///
/// ```
@@ -99,6 +134,8 @@ pub trait SliceRandom {
/// println!("{:?}", choices.choose_weighted(&mut rng, |item| item.1).unwrap().0);
/// ```
/// [`choose`]: SliceRandom::choose
+ /// [`choose_weighted_mut`]: SliceRandom::choose_weighted_mut
+ /// [`distributions::weighted`]: crate::distributions::weighted
#[cfg(feature = "alloc")]
fn choose_weighted(
&self, rng: &mut R, weight: F,
@@ -113,15 +150,19 @@ pub trait SliceRandom {
+ Clone
+ Default;
- /// Similar to [`choose_mut`], where the likelihood of each outcome may be
- /// specified. The specified function `weight` maps items `x` to a relative
+ /// Similar to [`choose_mut`], but where the likelihood of each outcome may
+ /// be specified.
+ ///
+ /// The specified function `weight` maps each item `x` to a relative
/// likelihood `weight(x)`. The probability of each item being selected is
/// therefore `weight(x) / s`, where `s` is the sum of all `weight(x)`.
///
- /// See also [`choose_weighted`].
+ /// For slices of length `n`, complexity is `O(n)`.
+ /// See also [`choose_weighted`], [`distributions::weighted`].
///
/// [`choose_mut`]: SliceRandom::choose_mut
/// [`choose_weighted`]: SliceRandom::choose_weighted
+ /// [`distributions::weighted`]: crate::distributions::weighted
#[cfg(feature = "alloc")]
fn choose_weighted_mut(
&mut self, rng: &mut R, weight: F,
@@ -138,8 +179,7 @@ pub trait SliceRandom {
/// Shuffle a mutable slice in place.
///
- /// Depending on the implementation, complexity is expected to be `O(n)`,
- /// where `n` is the length of the slice.
+ /// For slices of length `n`, complexity is `O(n)`.
///
/// # Example
///
@@ -172,7 +212,7 @@ pub trait SliceRandom {
/// If `amount` is greater than the number of elements in the slice, this
/// will perform a full shuffle.
///
- /// Complexity is expected to be `O(m)` where `m = amount`.
+ /// For slices, complexity is `O(m)` where `m = amount`.
fn partial_shuffle(
&mut self, rng: &mut R, amount: usize,
) -> (&mut [Self::Item], &mut [Self::Item])
@@ -180,19 +220,37 @@ pub trait SliceRandom {
}
/// Extension trait on iterators, providing random sampling methods.
+///
+/// This trait is implemented on all sized iterators, providing methods for
+/// choosing one or more elements. You must `use` this trait:
+///
+/// ```
+/// use rand::seq::IteratorRandom;
+///
+/// fn main() {
+/// let mut rng = rand::thread_rng();
+///
+/// let faces = "😀😎😐😕😠😢";
+/// println!("I am {}!", faces.chars().choose(&mut rng).unwrap());
+/// }
+/// ```
+/// Example output (non-deterministic):
+/// ```none
+/// I am 😀!
+/// ```
pub trait IteratorRandom: Iterator + Sized {
- /// Choose one element at random from the iterator. If you have a slice,
- /// it's significantly faster to call the [`choose`] or [`choose_mut`]
- /// functions using the slice instead.
- ///
+ /// Choose one element at random from the iterator.
+ ///
/// Returns `None` if and only if the iterator is empty.
///
- /// Complexity is `O(n)`, where `n` is the length of the iterator.
- /// This likely consumes multiple random numbers, but the exact number
- /// is unspecified.
- ///
- /// [`choose`]: SliceRandom::method.choose
- /// [`choose_mut`]: SliceRandom::choose_mut
+ /// This method uses [`Iterator::size_hint`] for optimisation. With an
+ /// accurate hint and where [`Iterator::nth`] is a constant-time operation
+ /// this method can offer `O(1)` performance. Where no size hint is
+ /// available, complexity is `O(n)` where `n` is the iterator length.
+ /// Partial hints (where `lower > 0`) also improve performance.
+ ///
+ /// For slices, prefer [`SliceRandom::choose`] which guarantees `O(1)`
+ /// performance.
fn choose(mut self, rng: &mut R) -> Option
where R: Rng + ?Sized {
let (mut lower, mut upper) = self.size_hint();
@@ -251,6 +309,7 @@ pub trait IteratorRandom: Iterator + Sized {
/// case this equals the number of elements available.
///
/// Complexity is `O(n)` where `n` is the length of the iterator.
+ /// For slices, prefer [`SliceRandom::choose_multiple`].
fn choose_multiple_fill(mut self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where R: Rng + ?Sized {
let amount = buf.len();
@@ -288,6 +347,7 @@ pub trait IteratorRandom: Iterator + Sized {
/// elements available.
///
/// Complexity is `O(n)` where `n` is the length of the iterator.
+ /// For slices, prefer [`SliceRandom::choose_multiple`].
#[cfg(feature = "alloc")]
fn choose_multiple(mut self, rng: &mut R, amount: usize) -> Vec
where R: Rng + ?Sized {
@@ -418,7 +478,10 @@ impl SliceRandom for [T] {
impl IteratorRandom for I where I: Iterator + Sized {}
-/// Iterator over multiple choices, as returned by [`SliceRandom::choose_multiple]
+/// An iterator over multiple slice elements.
+///
+/// This struct is created by
+/// [`SliceRandom::choose_multiple`](trait.SliceRandom.html#tymethod.choose_multiple).
#[cfg(feature = "alloc")]
#[derive(Debug)]
pub struct SliceChooseIter<'a, S: ?Sized + 'a, T: 'a> {