Skip to content

Rename gen_iter → random_iter, misc.. #1500

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 1, 2024
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
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