Skip to content
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

Add missing Debug implementation for librand structs #39156

Merged
merged 2 commits into from
Jan 21, 2017
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
11 changes: 11 additions & 0 deletions src/librand/chacha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

//! The ChaCha random number generator.

use core::fmt;
use {Rand, Rng, SeedableRng};

const KEY_WORDS: usize = 8; // 8 words for the 256-bit key
Expand All @@ -32,6 +33,16 @@ pub struct ChaChaRng {
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],
Expand Down
19 changes: 19 additions & 0 deletions src/librand/distributions/exponential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

//! The exponential distribution.

use core::fmt;

#[cfg(not(test))] // only necessary for no_std
use FloatMath;

Expand Down Expand Up @@ -55,6 +57,14 @@ impl Rand for Exp1 {
}
}

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 *
Expand All @@ -79,13 +89,22 @@ impl Sample<f64> for Exp {
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>();
n * self.lambda_inverse
}
}

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};
Expand Down
52 changes: 52 additions & 0 deletions src/librand/distributions/gamma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

//! The Gamma and derived distributions.

use core::fmt;

use self::GammaRepr::*;
use self::ChiSquaredRepr::*;

Expand Down Expand Up @@ -44,6 +46,19 @@ pub struct Gamma {
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),
Expand Down Expand Up @@ -182,6 +197,18 @@ pub struct ChiSquared {
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-
Expand All @@ -203,11 +230,13 @@ impl ChiSquared {
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 {
Expand Down Expand Up @@ -248,17 +277,29 @@ impl FisherF {
}
}
}

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 {
Expand All @@ -277,18 +318,29 @@ impl 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>();
norm * (self.dof / self.chi.ind_sample(rng)).sqrt()
}
}

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};
Expand Down
26 changes: 26 additions & 0 deletions src/librand/distributions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
//! 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;

Expand Down Expand Up @@ -78,6 +80,12 @@ impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
}
}

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
Expand All @@ -86,6 +94,15 @@ pub struct Weighted<T> {
pub item: T,
}

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
Expand Down Expand Up @@ -189,6 +206,15 @@ impl<'a, T: Clone> IndependentSample<T> for WeightedChoice<'a, T> {
}
}

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
Expand Down
31 changes: 31 additions & 0 deletions src/librand/distributions/normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

//! The normal and derived distributions.

use core::fmt;

#[cfg(not(test))] // only necessary for no_std
use FloatMath;

Expand Down Expand Up @@ -73,6 +75,14 @@ impl Rand for StandardNormal {
}
}

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
Expand All @@ -98,18 +108,29 @@ impl Normal {
}
}
}

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>();
self.mean + self.std_dev * n
}
}

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)`.
///
Expand All @@ -132,17 +153,27 @@ impl LogNormal {
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};
Expand Down
12 changes: 12 additions & 0 deletions src/librand/distributions/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

// this is surprisingly complicated to be both generic & correct

use core::fmt;
use core::marker::Sized;
use Rng;
use distributions::{IndependentSample, Sample};
Expand Down Expand Up @@ -50,12 +51,23 @@ impl<Sup: SampleRange> Sample<Sup> for Range<Sup> {
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> 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`.
Expand Down
Loading