//! The ChaCha random number generator.
+use core::fmt;
use {Rand, Rng, SeedableRng};
const KEY_WORDS: usize = 8; // 8 words for the 256-bit key
index: usize, // Index into state
}
+impl fmt::Debug for ChaChaRng {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("ChaChaRng")
+ .field("buffer", &self.buffer.iter())
+ .field("state", &self.state.iter())
+ .field("index", &self.index)
+ .finish()
+ }
+}
+
static EMPTY: ChaChaRng = ChaChaRng {
buffer: [0; STATE_WORDS],
state: [0; STATE_WORDS],
//! The exponential distribution.
+use core::fmt;
+
#[cfg(not(test))] // only necessary for no_std
use FloatMath;
}
}
+impl fmt::Debug for Exp1 {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_tuple("Exp1")
+ .field(&self.0)
+ .finish()
+ }
+}
+
/// The exponential distribution `Exp(lambda)`.
///
/// This distribution has density function: `f(x) = lambda *
self.ind_sample(rng)
}
}
+
impl IndependentSample<f64> for Exp {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
let Exp1(n) = rng.gen::<Exp1>();
}
}
+impl fmt::Debug for Exp {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Exp")
+ .field("lambda_inverse", &self.lambda_inverse)
+ .finish()
+ }
+}
+
#[cfg(test)]
mod tests {
use distributions::{IndependentSample, Sample};
//! The Gamma and derived distributions.
+use core::fmt;
+
use self::GammaRepr::*;
use self::ChiSquaredRepr::*;
repr: GammaRepr,
}
+impl fmt::Debug for Gamma {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Gamma")
+ .field("repr",
+ &match self.repr {
+ GammaRepr::Large(_) => "Large",
+ GammaRepr::One(_) => "Exp",
+ GammaRepr::Small(_) => "Small"
+ })
+ .finish()
+ }
+}
+
enum GammaRepr {
Large(GammaLargeShape),
One(Exp),
repr: ChiSquaredRepr,
}
+impl fmt::Debug for ChiSquared {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("ChiSquared")
+ .field("repr",
+ &match self.repr {
+ ChiSquaredRepr::DoFExactlyOne => "DoFExactlyOne",
+ ChiSquaredRepr::DoFAnythingElse(_) => "DoFAnythingElse",
+ })
+ .finish()
+ }
+}
+
enum ChiSquaredRepr {
// k == 1, Gamma(alpha, ..) is particularly slow for alpha < 1,
// e.g. when alpha = 1/2 as it would be for this case, so special-
ChiSquared { repr: repr }
}
}
+
impl Sample<f64> for ChiSquared {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
+
impl IndependentSample<f64> for ChiSquared {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
match self.repr {
}
}
}
+
impl Sample<f64> for FisherF {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
+
impl IndependentSample<f64> for FisherF {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
self.numer.ind_sample(rng) / self.denom.ind_sample(rng) * self.dof_ratio
}
}
+impl fmt::Debug for FisherF {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("FisherF")
+ .field("numer", &self.numer)
+ .field("denom", &self.denom)
+ .field("dof_ratio", &self.dof_ratio)
+ .finish()
+ }
+}
+
/// The Student t distribution, `t(nu)`, where `nu` is the degrees of
/// freedom.
pub struct StudentT {
}
}
}
+
impl Sample<f64> for StudentT {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
+
impl IndependentSample<f64> for StudentT {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
let StandardNormal(norm) = rng.gen::<StandardNormal>();
}
}
+impl fmt::Debug for StudentT {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("StudentT")
+ .field("chi", &self.chi)
+ .field("dof", &self.dof)
+ .finish()
+ }
+}
+
#[cfg(test)]
mod tests {
use distributions::{IndependentSample, Sample};
//! internally. The `IndependentSample` trait is for generating values
//! that do not need to record state.
+use core::fmt;
+
#[cfg(not(test))] // only necessary for no_std
use core::num::Float;
}
}
+impl<Sup> fmt::Debug for RandSample<Sup> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("RandSample { .. }")
+ }
+}
+
/// A value with a particular weight for use with `WeightedChoice`.
pub struct Weighted<T> {
/// The numerical weight of this item
pub item: T,
}
+impl<T> fmt::Debug for Weighted<T> {
+ default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("Weighted")
+ }
+}
+
+impl<T: fmt::Debug> fmt::Debug for Weighted<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Weighted")
+ .field("weight", &self.weight)
+ .field("item", &self.item)
+ .finish()
+ }
+}
+
/// A distribution that selects from a finite collection of weighted items.
///
/// Each item has an associated weight that influences how likely it
}
}
+impl<'a, T> fmt::Debug for WeightedChoice<'a, T> {
+ default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("WeightedChoice")
+ }
+}
+
+impl<'a, T: fmt::Debug> fmt::Debug for WeightedChoice<'a, T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("WeightedChoice")
+ .field("items", &self.items)
+ .field("weight_range", &self.weight_range)
+ .finish()
+ }
+}
+
mod ziggurat_tables;
/// Sample a random number using the Ziggurat method (specifically the
//! The normal and derived distributions.
+use core::fmt;
+
#[cfg(not(test))] // only necessary for no_std
use FloatMath;
}
}
+impl fmt::Debug for StandardNormal {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_tuple("StandardNormal")
+ .field(&self.0)
+ .finish()
+ }
+}
+
/// The normal distribution `N(mean, std_dev**2)`.
///
/// This uses the ZIGNOR variant of the Ziggurat method, see
}
}
}
+
impl Sample<f64> for Normal {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
+
impl IndependentSample<f64> for Normal {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
let StandardNormal(n) = rng.gen::<StandardNormal>();
}
}
+impl fmt::Debug for Normal {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Normal")
+ .field("mean", &self.mean)
+ .field("std_dev", &self.std_dev)
+ .finish()
+ }
+}
+
/// The log-normal distribution `ln N(mean, std_dev**2)`.
///
LogNormal { norm: Normal::new(mean, std_dev) }
}
}
+
impl Sample<f64> for LogNormal {
fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
self.ind_sample(rng)
}
}
+
impl IndependentSample<f64> for LogNormal {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
self.norm.ind_sample(rng).exp()
}
}
+impl fmt::Debug for LogNormal {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("LogNormal")
+ .field("norm", &self.norm)
+ .finish()
+ }
+}
+
#[cfg(test)]
mod tests {
use distributions::{IndependentSample, Sample};
// this is surprisingly complicated to be both generic & correct
+use core::fmt;
use core::marker::Sized;
use Rng;
use distributions::{IndependentSample, Sample};
self.ind_sample(rng)
}
}
+
impl<Sup: SampleRange> IndependentSample<Sup> for Range<Sup> {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
SampleRange::sample_range(self, rng)
}
}
+impl<X> fmt::Debug for Range<X> {
+ default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("Range { .. }")
+ }
+}
+
+impl<X: fmt::Debug> fmt::Debug for Range<X> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Range")
+ .field("low", &self.low)
+ .field("range", &self.range)
+ .field("accept_zone", &self.accept_zone)
+ .finish()
+ }
+}
+
/// The helper trait for types that have a sensible way to sample
/// uniformly between two values. This should not be used directly,
/// and is only to facilitate `Range`.
#![allow(non_camel_case_types)]
+use core::fmt;
use core::slice;
use core::iter::repeat;
use core::num::Wrapping as w;
c: w32,
}
+impl fmt::Debug for IsaacRng {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("IsaacRng")
+ .field("cnt", &self.cnt)
+ .field("rsl", &self.rsl.iter())
+ .field("mem", &self.mem.iter())
+ .field("a", &self.a)
+ .field("b", &self.b)
+ .field("c", &self.c)
+ .finish()
+ }
+}
+
static EMPTY: IsaacRng = IsaacRng {
cnt: 0,
rsl: [w(0); RAND_SIZE_USIZE],
c: w64,
}
+impl fmt::Debug for Isaac64Rng {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Isaac64Rng")
+ .field("cnt", &self.cnt)
+ .field("rsl", &self.rsl.iter())
+ .field("mem", &self.mem.iter())
+ .field("a", &self.a)
+ .field("b", &self.b)
+ .field("c", &self.c)
+ .finish()
+ }
+}
+
static EMPTY_64: Isaac64Rng = Isaac64Rng {
cnt: 0,
rsl: [w(0); RAND_SIZE_64],
html_playground_url = "https://play.rust-lang.org/",
test(attr(deny(warnings))))]
#![deny(warnings)]
+#![deny(missing_debug_implementations)]
#![no_std]
#![unstable(feature = "rand",
reason = "use `rand` from crates.io",
#![feature(staged_api)]
#![feature(step_by)]
#![feature(custom_attribute)]
+#![feature(specialization)]
#![allow(unused_attributes)]
#![cfg_attr(not(test), feature(core_float))] // only necessary for no_std
#[macro_use]
extern crate std;
+use core::fmt;
use core::f64;
use core::intrinsics;
use core::marker::PhantomData;
}
}
+impl<'a, T, R> fmt::Debug for Generator<'a, T, R> {
+ default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("Generator { .. }")
+ }
+}
+
+impl<'a, T, R: fmt::Debug> fmt::Debug for Generator<'a, T, R> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Generator")
+ .field("rng", &self.rng)
+ .finish()
+ }
+}
+
/// Iterator which will continuously generate random ascii characters.
///
/// This iterator is created via the `gen_ascii_chars` method on `Rng`.
}
}
+impl<'a, R> fmt::Debug for AsciiGenerator<'a, R> {
+ default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("AsciiGenerator { .. }")
+ }
+}
+
+impl<'a, R: fmt::Debug> fmt::Debug for AsciiGenerator<'a, R> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("AsciiGenerator")
+ .field("rng", &self.rng)
+ .finish()
+ }
+}
+
/// A random number generator that can be explicitly seeded to produce
/// the same stream of randomness multiple times.
pub trait SeedableRng<Seed>: Rng {
/// [1]: Marsaglia, George (July 2003). ["Xorshift
/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
/// Statistical Software*. Vol. 8 (Issue 14).
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct XorShiftRng {
x: u32,
y: u32,
/// `[0,1)`.
pub struct Open01<F>(pub F);
+impl<F> fmt::Debug for Open01<F> {
+ default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("Open01 { .. }")
+ }
+}
+
+impl<F: fmt::Debug> fmt::Debug for Open01<F> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_tuple("Open01")
+ .field(&self.0)
+ .finish()
+ }
+}
+
/// A wrapper for generating floating point numbers uniformly in the
/// closed interval `[0,1]` (including both endpoints).
///
/// `[0,1)`.
pub struct Closed01<F>(pub F);
+impl<F> fmt::Debug for Closed01<F> {
+ default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("Closed01 { .. }")
+ }
+}
+
+impl<F: fmt::Debug> fmt::Debug for Closed01<F> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_tuple("Closed01")
+ .field(&self.0)
+ .finish()
+ }
+}
+
#[cfg(test)]
mod test {
use std::__rand as rand;
//! A wrapper around another RNG that reseeds it after it
//! generates a certain number of random bytes.
+use core::fmt;
use {Rng, SeedableRng};
/// How many bytes of entropy the underling RNG is allowed to generate
}
}
-
impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> {
fn next_u32(&mut self) -> u32 {
self.reseed_if_necessary();
}
}
+impl<R, Rsdr> fmt::Debug for ReseedingRng<R, Rsdr> {
+ default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("ReseedingRng { .. }")
+ }
+}
+
+impl<R: fmt::Debug, Rsdr: fmt::Debug> fmt::Debug for ReseedingRng<R, Rsdr> {
+ default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("ReseedingRng")
+ .field("rng", &self.rng)
+ .field("generation_threshold", &self.generation_threshold)
+ .field("bytes_generated", &self.bytes_generated)
+ .field("reseeder", &self.reseeder)
+ .finish()
+ }
+}
+
/// Something that can be used to reseed an RNG via `ReseedingRng`.
pub trait Reseeder<R> {
/// Reseed the given RNG.
/// Reseed an RNG using a `Default` instance. This reseeds by
/// replacing the RNG with the result of a `Default::default` call.
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
pub struct ReseedWithDefault;
impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {