Skip to content

Commit

Permalink
migrate to num-traits, raise MSRV to 1.36
Browse files Browse the repository at this point in the history
  • Loading branch information
newpavlov committed Jun 20, 2020
1 parent 2c2fbd6 commit 3367a48
Show file tree
Hide file tree
Showing 23 changed files with 237 additions and 369 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ sudo: false

matrix:
include:
- rust: 1.32.0
name: "Linux, 1.32.0"
- rust: 1.36.0
name: "Linux, 1.36.0"
env: ALLOC=0
os: linux

Expand Down
10 changes: 9 additions & 1 deletion rand_distr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,17 @@ travis-ci = { repository = "rust-random/rand" }
appveyor = { repository = "rust-random/rand" }

[dependencies]
rand = { path = "..", version = "0.7" }
rand = { path = "..", version = "0.7", default-features = false }
num-traits = { version = "0.2", default-features = false, features = ["libm"] }

[features]
default = ["std"]
std = ["rand/std", "num-traits/std", "alloc"]
alloc = ["rand/alloc"]

[dev-dependencies]
rand_pcg = { version = "0.2", path = "../rand_pcg" }
# For inline examples
rand = { path = "..", version = "0.7", default-features = false, features = ["std_rng", "std"] }
# Histogram implementation for testing uniformity
average = "0.10.3"
9 changes: 5 additions & 4 deletions rand_distr/src/binomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

use crate::{Distribution, Uniform};
use rand::Rng;
use std::{error, fmt};
use core::fmt;

/// The binomial distribution `Binomial(n, p)`.
///
Expand Down Expand Up @@ -53,7 +53,8 @@ impl fmt::Display for Error {
}
}

impl error::Error for Error {}
#[cfg(feature = "std")]
impl std::error::Error for Error {}

impl Binomial {
/// Construct a new `Binomial` with the given shape parameters `n` (number
Expand All @@ -72,7 +73,7 @@ impl Binomial {
/// Convert a `f64` to an `i64`, panicing on overflow.
// In the future (Rust 1.34), this might be replaced with `TryFrom`.
fn f64_to_i64(x: f64) -> i64 {
assert!(x < (::std::i64::MAX as f64));
assert!(x < (core::i64::MAX as f64));
x as i64
}

Expand Down Expand Up @@ -106,7 +107,7 @@ impl Distribution<u64> for Binomial {
// Ranlib uses 30, and GSL uses 14.
const BINV_THRESHOLD: f64 = 10.;

if (self.n as f64) * p < BINV_THRESHOLD && self.n <= (::std::i32::MAX as u64) {
if (self.n as f64) * p < BINV_THRESHOLD && self.n <= (core::i32::MAX as u64) {
// Use the BINV algorithm.
let s = p / q;
let a = ((self.n + 1) as f64) * s;
Expand Down
23 changes: 13 additions & 10 deletions rand_distr/src/cauchy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

//! The Cauchy distribution.

use crate::utils::Float;
use num_traits::{Float, FloatConst};
use crate::{Distribution, Standard};
use rand::Rng;
use std::{error, fmt};
use core::fmt;

/// The Cauchy distribution `Cauchy(median, scale)`.
///
Expand Down Expand Up @@ -52,30 +52,31 @@ impl fmt::Display for Error {
}
}

impl error::Error for Error {}
#[cfg(feature = "std")]
impl std::error::Error for Error {}

impl<N: Float> Cauchy<N>
impl<N: Float + FloatConst> Cauchy<N>
where Standard: Distribution<N>
{
/// Construct a new `Cauchy` with the given shape parameters
/// `median` the peak location and `scale` the scale factor.
pub fn new(median: N, scale: N) -> Result<Cauchy<N>, Error> {
if !(scale > N::from(0.0)) {
if !(scale > N::zero()) {
return Err(Error::ScaleTooSmall);
}
Ok(Cauchy { median, scale })
}
}

impl<N: Float> Distribution<N> for Cauchy<N>
impl<N: Float + FloatConst> Distribution<N> for Cauchy<N>
where Standard: Distribution<N>
{
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> N {
// sample from [0, 1)
let x = Standard.sample(rng);
// get standard cauchy random number
// note that π/2 is not exactly representable, even if x=0.5 the result is finite
let comp_dev = (N::pi() * x).tan();
let comp_dev = (N::PI() * x).tan();
// shift and scale according to parameters
self.median + self.scale * comp_dev
}
Expand Down Expand Up @@ -108,10 +109,12 @@ mod test {
sum += numbers[i];
}
let median = median(&mut numbers);
println!("Cauchy median: {}", median);
#[cfg(feature = "std")]
std::println!("Cauchy median: {}", median);
assert!((median - 10.0).abs() < 0.4); // not 100% certain, but probable enough
let mean = sum / 1000.0;
println!("Cauchy mean: {}", mean);
#[cfg(feature = "std")]
std::println!("Cauchy mean: {}", mean);
// for a Cauchy distribution the mean should not converge
assert!((mean - 10.0).abs() > 0.4); // not 100% certain, but probable enough
}
Expand All @@ -130,7 +133,7 @@ mod test {

#[test]
fn value_stability() {
fn gen_samples<N: Float + core::fmt::Debug>(m: N, s: N, buf: &mut [N])
fn gen_samples<N: Float + FloatConst + core::fmt::Debug>(m: N, s: N, buf: &mut [N])
where Standard: Distribution<N> {
let distr = Cauchy::new(m, s).unwrap();
let mut rng = crate::test::rng(353);
Expand Down
26 changes: 14 additions & 12 deletions rand_distr/src/dirichlet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
// except according to those terms.

//! The dirichlet distribution.

use crate::utils::Float;
#![cfg(feature = "alloc")]
use num_traits::Float;
use crate::{Distribution, Exp1, Gamma, Open01, StandardNormal};
use rand::Rng;
use std::{error, fmt};
use core::fmt;
use alloc::{vec, vec::Vec};

/// The Dirichlet distribution `Dirichlet(alpha)`.
///
Expand Down Expand Up @@ -58,7 +59,8 @@ impl fmt::Display for Error {
}
}

impl error::Error for Error {}
#[cfg(feature = "std")]
impl std::error::Error for Error {}

impl<N: Float> Dirichlet<N>
where
Expand All @@ -76,7 +78,7 @@ where
return Err(Error::AlphaTooShort);
}
for &ai in &a {
if !(ai > N::from(0.0)) {
if !(ai > N::zero()) {
return Err(Error::AlphaTooSmall);
}
}
Expand All @@ -89,7 +91,7 @@ where
/// Requires `size >= 2`.
#[inline]
pub fn new_with_size(alpha: N, size: usize) -> Result<Dirichlet<N>, Error> {
if !(alpha > N::from(0.0)) {
if !(alpha > N::zero()) {
return Err(Error::AlphaTooSmall);
}
if size < 2 {
Expand All @@ -109,17 +111,17 @@ where
{
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec<N> {
let n = self.alpha.len();
let mut samples = vec![N::from(0.0); n];
let mut sum = N::from(0.0);
let mut samples = vec![N::zero(); n];
let mut sum = N::zero();

for (s, &a) in samples.iter_mut().zip(self.alpha.iter()) {
let g = Gamma::new(a, N::from(1.0)).unwrap();
let g = Gamma::new(a, N::one()).unwrap();
*s = g.sample(rng);
sum += *s;
sum = sum + (*s);
}
let invacc = N::from(1.0) / sum;
let invacc = N::one() / sum;
for s in samples.iter_mut() {
*s *= invacc;
*s = (*s)*invacc;
}
samples
}
Expand Down
12 changes: 7 additions & 5 deletions rand_distr/src/exponential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

//! The exponential distribution.

use crate::utils::{ziggurat, Float};
use crate::utils::ziggurat;
use num_traits::Float;
use crate::{ziggurat_tables, Distribution};
use rand::Rng;
use std::{error, fmt};
use core::fmt;

/// Samples floating-point numbers according to the exponential distribution,
/// with rate parameter `λ = 1`. This is equivalent to `Exp::new(1.0)` or
Expand Down Expand Up @@ -110,7 +111,8 @@ impl fmt::Display for Error {
}
}

impl error::Error for Error {}
#[cfg(feature = "std")]
impl std::error::Error for Error {}

impl<N: Float> Exp<N>
where Exp1: Distribution<N>
Expand All @@ -119,11 +121,11 @@ where Exp1: Distribution<N>
/// `lambda`.
#[inline]
pub fn new(lambda: N) -> Result<Exp<N>, Error> {
if !(lambda > N::from(0.0)) {
if !(lambda > N::zero()) {
return Err(Error::LambdaTooSmall);
}
Ok(Exp {
lambda_inverse: N::from(1.0) / lambda,
lambda_inverse: N::one() / lambda,
})
}
}
Expand Down

0 comments on commit 3367a48

Please sign in to comment.