Skip to content

Commit

Permalink
Rename gen_iter → random_iter, misc.. (#1500)
Browse files Browse the repository at this point in the history
This extracts the non-inherent-methods stuff from #1492.
  • Loading branch information
dhardy authored Oct 1, 2024
1 parent e2092e9 commit 66b11eb
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 89 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
- Require `Clone` and `AsRef` bound for `SeedableRng::Seed`. (#1491)
- Implement `Distribution<u64>` for `Poisson<f64>` (#1498)
- Limit the maximal acceptable lambda for `Poisson` to solve (#1312) (#1498)
- Rename `Rng::gen_iter` to `random_iter` (#1500)

## [0.9.0-alpha.1] - 2024-03-18
- Add the `Slice::num_choices` method to the Slice distribution (#1402)
Expand Down
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,31 @@
[![API](https://img.shields.io/badge/api-master-yellow.svg)](https://rust-random.github.io/rand/rand)
[![API](https://docs.rs/rand/badge.svg)](https://docs.rs/rand)

A Rust library for random number generation, featuring:
Rand is a Rust library supporting random generators:

- Easy random value generation and usage via the [`Rng`](https://docs.rs/rand/*/rand/trait.Rng.html),
[`SliceRandom`](https://docs.rs/rand/*/rand/seq/trait.SliceRandom.html) and
[`IteratorRandom`](https://docs.rs/rand/*/rand/seq/trait.IteratorRandom.html) traits
- Secure seeding via the [`getrandom` crate](https://crates.io/crates/getrandom)
and fast, convenient generation via [`thread_rng`](https://docs.rs/rand/*/rand/fn.thread_rng.html)
- A modular design built over [`rand_core`](https://crates.io/crates/rand_core)
([see the book](https://rust-random.github.io/book/crates.html))
- A standard RNG trait: [`rand_core::RngCore`](https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html)
- Fast implementations of the best-in-class [cryptographic](https://rust-random.github.io/book/guide-rngs.html#cryptographically-secure-pseudo-random-number-generators-csprngs) and
[non-cryptographic](https://rust-random.github.io/book/guide-rngs.html#basic-pseudo-random-number-generators-prngs) generators
[non-cryptographic](https://rust-random.github.io/book/guide-rngs.html#basic-pseudo-random-number-generators-prngs) generators: [`rand::rngs`](https://docs.rs/rand/latest/rand/rngs/index.html), and more RNGs: [`rand_chacha`](https://docs.rs/rand_chacha), [`rand_xoshiro`](https://docs.rs/rand_xoshiro/), [`rand_pcg`](https://docs.rs/rand_pcg/), [rngs repo](https://github.com/rust-random/rngs/)
- [`rand::thread_rng`](https://docs.rs/rand/latest/rand/fn.thread_rng.html) is an asymtotically-fast, reasonably secure generator available on all `std` targets
- Secure seeding via the [`getrandom` crate](https://crates.io/crates/getrandom)

Supporting random value generation and random processes:

- [`Standard`](https://docs.rs/rand/latest/rand/distributions/struct.Standard.html) random value generation
- Ranged [`Uniform`](https://docs.rs/rand/latest/rand/distributions/struct.Uniform.html) number generation for many types
- A flexible [`distributions`](https://docs.rs/rand/*/rand/distr/index.html) module
- Samplers for a large number of random number distributions via our own
[`rand_distr`](https://docs.rs/rand_distr) and via
the [`statrs`](https://docs.rs/statrs/0.13.0/statrs/)
- Random processes (mostly choose and shuffle) via [`rand::seq`](https://docs.rs/rand/latest/rand/seq/index.html) traits

All with:

- [Portably reproducible output](https://rust-random.github.io/book/portability.html)
- `#[no_std]` compatibility (partial)
- *Many* performance optimisations

It's also worth pointing out what `rand` *is not*:
It's also worth pointing out what Rand *is not*:

- Small. Most low-level crates are small, but the higher-level `rand` and
`rand_distr` each contain a lot of functionality.
Expand Down Expand Up @@ -73,8 +78,7 @@ Rand is built with these features enabled by default:
- `alloc` (implied by `std`) enables functionality requiring an allocator
- `getrandom` (implied by `std`) is an optional dependency providing the code
behind `rngs::OsRng`
- `std_rng` enables inclusion of `StdRng`, `thread_rng` and `random`
(the latter two *also* require that `std` be enabled)
- `std_rng` enables inclusion of `StdRng`, `thread_rng`

Optionally, the following dependencies can be enabled:

Expand All @@ -94,8 +98,7 @@ experimental `simd_support` feature.
Rand supports limited functionality in `no_std` mode (enabled via
`default-features = false`). In this case, `OsRng` and `from_os_rng` are
unavailable (unless `getrandom` is enabled), large parts of `seq` are
unavailable (unless `alloc` is enabled), and `thread_rng` and `random` are
unavailable.
unavailable (unless `alloc` is enabled), and `thread_rng` is unavailable.

## Portability and platform support

Expand Down
2 changes: 1 addition & 1 deletion benches/benches/seq_choose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ criterion_group!(
criterion_main!(benches);

pub fn bench(c: &mut Criterion) {
c.bench_function("seq_slice_choose_1_of_1000", |b| {
c.bench_function("seq_slice_choose_1_of_100", |b| {
let mut rng = Pcg32::from_rng(thread_rng());
let mut buf = [0i32; 100];
rng.fill(&mut buf);
Expand Down
6 changes: 3 additions & 3 deletions rand_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ pub use getrandom;
#[cfg(feature = "getrandom")]
pub use os::OsRng;

/// The core of a random number generator.
/// Implementation-level interface for RNGs
///
/// This trait encapsulates the low-level functionality common to all
/// generators, and is the "back end", to be implemented by generators.
/// End users should normally use the `Rng` trait from the [`rand`] crate,
/// End users should normally use the [`rand::Rng`] trait
/// which is automatically implemented for every type implementing `RngCore`.
///
/// Three different methods for generating random data are provided since the
Expand Down Expand Up @@ -129,7 +129,7 @@ pub use os::OsRng;
/// rand_core::impl_try_rng_from_rng_core!(CountingRng);
/// ```
///
/// [`rand`]: https://docs.rs/rand
/// [`rand::Rng`]: https://docs.rs/rand/latest/rand/trait.Rng.html
/// [`fill_bytes`]: RngCore::fill_bytes
/// [`next_u32`]: RngCore::next_u32
/// [`next_u64`]: RngCore::next_u64
Expand Down
7 changes: 4 additions & 3 deletions rand_distr/src/weighted_alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,10 @@ where
}
}

/// Trait that must be implemented for weights, that are used with
/// [`WeightedAliasIndex`]. Currently no guarantees on the correctness of
/// [`WeightedAliasIndex`] are given for custom implementations of this trait.
/// Weight bound for [`WeightedAliasIndex`]
///
/// Currently no guarantees on the correctness of [`WeightedAliasIndex`] are
/// given for custom implementations of this trait.
pub trait AliasableWeight:
Sized
+ Copy
Expand Down
23 changes: 11 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,24 @@
//!
//! # Quick Start
//!
//! To get you started quickly, the easiest and highest-level way to get
//! a random value is to use [`random()`]; alternatively you can use
//! [`thread_rng()`]. The [`Rng`] trait provides a useful API on all RNGs, while
//! the [`distr`] and [`seq`] modules provide further
//! functionality on top of RNGs.
//!
//! ```
//! // The prelude import enables methods we use below, specifically
//! // Rng::random, Rng::sample, SliceRandom::shuffle and IndexedRandom::choose.
//! use rand::prelude::*;
//!
//! if rand::random() { // generates a boolean
//! // Try printing a random unicode code point (probably a bad idea)!
//! println!("char: {}", rand::random::<char>());
//! }
//!
//! // Get an RNG:
//! let mut rng = rand::thread_rng();
//! let y: f64 = rng.random(); // generates a float between 0 and 1
//!
//! // Try printing a random unicode code point (probably a bad idea)!
//! println!("char: '{}'", rng.random::<char>());
//! // Try printing a random alphanumeric value instead!
//! println!("alpha: '{}'", rng.sample(rand::distr::Alphanumeric) as char);
//!
//! // Generate and shuffle a sequence:
//! let mut nums: Vec<i32> = (1..100).collect();
//! nums.shuffle(&mut rng);
//! // And take a random pick (yes, we didn't need to shuffle first!):
//! let _ = nums.choose(&mut rng);
//! ```
//!
//! # The Book
Expand Down
108 changes: 56 additions & 52 deletions src/rng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ use core::num::Wrapping;
use core::{mem, slice};
use rand_core::RngCore;

/// An automatically-implemented extension trait on [`RngCore`] providing high-level
/// generic methods for sampling values and other convenience methods.
/// User-level interface for RNGs
///
/// This is the primary trait to use when generating random values.
/// [`RngCore`] is the `dyn`-safe implementation-level interface for Random
/// (Number) Generators. This trait, `Rng`, provides a user-level interface on
/// RNGs. It is implemented automatically for any `R: RngCore`.
///
/// This trait must usually be brought into scope via `use rand::Rng;` or
/// `use rand::prelude::*;`.
///
/// # Generic usage
///
Expand Down Expand Up @@ -96,67 +100,25 @@ pub trait Rng: RngCore {
Standard.sample(self)
}

/// Generate a random value in the given range.
///
/// This function is optimised for the case that only a single sample is
/// made from the given range. See also the [`Uniform`] distribution
/// type which may be faster if sampling from the same range repeatedly.
///
/// All types support `low..high_exclusive` and `low..=high` range syntax.
/// Unsigned integer types also support `..high_exclusive` and `..=high` syntax.
///
/// # Panics
///
/// Panics if the range is empty, or if `high - low` overflows for floats.
///
/// # Example
///
/// ```
/// use rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
///
/// // Exclusive range
/// let n: u32 = rng.gen_range(..10);
/// println!("{}", n);
/// let m: f64 = rng.gen_range(-40.0..1.3e5);
/// println!("{}", m);
///
/// // Inclusive range
/// let n: u32 = rng.gen_range(..=10);
/// println!("{}", n);
/// ```
///
/// [`Uniform`]: distr::uniform::Uniform
#[track_caller]
fn gen_range<T, R>(&mut self, range: R) -> T
where
T: SampleUniform,
R: SampleRange<T>,
{
assert!(!range.is_empty(), "cannot sample empty range");
range.sample_single(self).unwrap()
}

/// Generate values via an iterator
/// Return an iterator over [`random`](Self::random) variates
///
/// This is a just a wrapper over [`Rng::sample_iter`] using
/// [`distr::Standard`].
///
/// Note: this method consumes its argument. Use
/// `(&mut rng).gen_iter()` to avoid consuming the RNG.
/// `(&mut rng).random_iter()` to avoid consuming the RNG.
///
/// # Example
///
/// ```
/// use rand::{rngs::mock::StepRng, Rng};
///
/// let rng = StepRng::new(1, 1);
/// let v: Vec<i32> = rng.gen_iter().take(5).collect();
/// let v: Vec<i32> = rng.random_iter().take(5).collect();
/// assert_eq!(&v, &[1, 2, 3, 4, 5]);
/// ```
#[inline]
fn gen_iter<T>(self) -> distr::DistIter<Standard, Self, T>
fn random_iter<T>(self) -> distr::DistIter<Standard, Self, T>
where
Self: Sized,
Standard: Distribution<T>,
Expand Down Expand Up @@ -247,6 +209,48 @@ pub trait Rng: RngCore {
dest.fill(self)
}

/// Generate a random value in the given range.
///
/// This function is optimised for the case that only a single sample is
/// made from the given range. See also the [`Uniform`] distribution
/// type which may be faster if sampling from the same range repeatedly.
///
/// All types support `low..high_exclusive` and `low..=high` range syntax.
/// Unsigned integer types also support `..high_exclusive` and `..=high` syntax.
///
/// # Panics
///
/// Panics if the range is empty, or if `high - low` overflows for floats.
///
/// # Example
///
/// ```
/// use rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
///
/// // Exclusive range
/// let n: u32 = rng.gen_range(..10);
/// println!("{}", n);
/// let m: f64 = rng.gen_range(-40.0..1.3e5);
/// println!("{}", m);
///
/// // Inclusive range
/// let n: u32 = rng.gen_range(..=10);
/// println!("{}", n);
/// ```
///
/// [`Uniform`]: distr::uniform::Uniform
#[track_caller]
fn gen_range<T, R>(&mut self, range: R) -> T
where
T: SampleUniform,
R: SampleRange<T>,
{
assert!(!range.is_empty(), "cannot sample empty range");
range.sample_single(self).unwrap()
}

/// Return a bool with a probability `p` of being true.
///
/// See also the [`Bernoulli`] distribution, which may be faster if
Expand Down Expand Up @@ -316,7 +320,7 @@ pub trait Rng: RngCore {
since = "0.9.0",
note = "Renamed to `random` to avoid conflict with the new `gen` keyword in Rust 2024."
)]
fn gen<T>(&mut self) -> T
fn r#gen<T>(&mut self) -> T
where
Standard: Distribution<T>,
{
Expand Down Expand Up @@ -474,8 +478,8 @@ mod test {
// Check equivalence for generated floats
let mut array = [0f32; 2];
rng.fill(&mut array);
let gen: [f32; 2] = rng.random();
assert_eq!(array, gen);
let arr2: [f32; 2] = rng.random();
assert_eq!(array, arr2);
}

#[test]
Expand Down
10 changes: 6 additions & 4 deletions src/seq/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,12 @@ where
}
}

/// Randomly sample exactly `amount` distinct indices from `0..length`, and
/// return them in an arbitrary order (there is no guarantee of shuffling or
/// ordering). The weights are to be provided by the input function `weights`,
/// which will be called once for each index.
/// Randomly sample exactly `amount` distinct indices from `0..length`
///
/// Results are in arbitrary order (there is no guarantee of shuffling or
/// ordering).
///
/// Function `weight` is called once for each index to provide weights.
///
/// This method is used internally by the slice sampling methods, but it can
/// sometimes be useful to have the indices themselves so this is provided as
Expand Down

0 comments on commit 66b11eb

Please sign in to comment.