From 5f0ebe156e17eb6682c728976061f8c67b0c1fd9 Mon Sep 17 00:00:00 2001 From: Richard McCormack Date: Mon, 6 May 2019 16:11:51 -0400 Subject: [PATCH 1/4] update rand to 0.6 and enable wasm-bindgen feature --- Cargo.toml | 2 +- src/data/transforms/shuffle.rs | 5 +++-- src/learning/nnet/net_layer.rs | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5502be8f..822385c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,5 +17,5 @@ datasets = [] [dependencies] num = { version = "0.1.41", default-features = false } -rand = "0.4.1" +rand = { version = "0.6", features = ["wasm-bindgen"] } rulinalg = { git = "https://github.com/AtheMathmo/rulinalg", rev = "1ed8b937" } diff --git a/src/data/transforms/shuffle.rs b/src/data/transforms/shuffle.rs index 9f29b7da..445769ae 100644 --- a/src/data/transforms/shuffle.rs +++ b/src/data/transforms/shuffle.rs @@ -27,7 +27,8 @@ use learning::LearningResult; use linalg::{Matrix, BaseMatrix, BaseMatrixMut}; use super::Transformer; -use rand::{Rng, thread_rng, ThreadRng}; +use rand::{Rng, thread_rng}; +use rand::rngs::ThreadRng; /// The `Shuffler` /// @@ -118,4 +119,4 @@ mod tests { assert_eq!(shuffled.into_vec(), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]); } -} \ No newline at end of file +} diff --git a/src/learning/nnet/net_layer.rs b/src/learning/nnet/net_layer.rs index 8239d7ab..502de09c 100644 --- a/src/learning/nnet/net_layer.rs +++ b/src/learning/nnet/net_layer.rs @@ -7,8 +7,8 @@ use learning::error::{Error, ErrorKind}; use learning::toolkit::activ_fn::ActivationFunc; use rand::thread_rng; -use rand::distributions::Sample; -use rand::distributions::normal::Normal; +use rand::distributions::Distribution; +use rand::distributions::Normal; use std::fmt::Debug; From 785c8ebbc46be5ba140a2c62b86a68ce004e76cc Mon Sep 17 00:00:00 2001 From: Richard McCormack Date: Mon, 6 May 2019 18:06:35 -0400 Subject: [PATCH 2/4] Gate wasm-bindgen for rand behind a wasm-bindgen feature --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 822385c2..099470be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,9 @@ license = "MIT" [features] stats = [] datasets = [] +wasm-bindgen = ["rand/wasm-bindgen"] [dependencies] num = { version = "0.1.41", default-features = false } -rand = { version = "0.6", features = ["wasm-bindgen"] } +rand = "0.6" rulinalg = { git = "https://github.com/AtheMathmo/rulinalg", rev = "1ed8b937" } From 634817b3bf8e0c523f3acbf8c71c969626b95a4c Mon Sep 17 00:00:00 2001 From: Richard McCormack Date: Mon, 6 May 2019 18:12:45 -0400 Subject: [PATCH 3/4] group imports --- src/learning/nnet/net_layer.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/learning/nnet/net_layer.rs b/src/learning/nnet/net_layer.rs index 502de09c..02452196 100644 --- a/src/learning/nnet/net_layer.rs +++ b/src/learning/nnet/net_layer.rs @@ -7,8 +7,7 @@ use learning::error::{Error, ErrorKind}; use learning::toolkit::activ_fn::ActivationFunc; use rand::thread_rng; -use rand::distributions::Distribution; -use rand::distributions::Normal; +use rand::distributions::{Distribution, Normal}; use std::fmt::Debug; From 3b7805ce7746f2ae3ad97767e191f592d03cef0b Mon Sep 17 00:00:00 2001 From: Richard McCormack Date: Thu, 21 Nov 2019 12:25:58 -0500 Subject: [PATCH 4/4] Rand 0.7 and update all features --- Cargo.toml | 3 ++- examples/k-means_generating_cluster.rs | 8 +++---- examples/naive_bayes_dogs.rs | 33 +++++++++++++------------- examples/nnet-and_gate.rs | 8 ++++--- src/data/transforms/shuffle.rs | 10 ++++---- src/lib.rs | 1 + src/stats/dist/exponential.rs | 19 +++++---------- src/stats/dist/gaussian.rs | 19 +++++---------- tests/learning/pca.rs | 2 +- 9 files changed, 47 insertions(+), 56 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 099470be..4f34ee30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,5 +18,6 @@ wasm-bindgen = ["rand/wasm-bindgen"] [dependencies] num = { version = "0.1.41", default-features = false } -rand = "0.6" +rand = "0.7" +rand_distr = "0.2" rulinalg = { git = "https://github.com/AtheMathmo/rulinalg", rev = "1ed8b937" } diff --git a/examples/k-means_generating_cluster.rs b/examples/k-means_generating_cluster.rs index 078851df..36c80321 100644 --- a/examples/k-means_generating_cluster.rs +++ b/examples/k-means_generating_cluster.rs @@ -1,13 +1,13 @@ extern crate rusty_machine; extern crate rand; +extern crate rand_distr; use rusty_machine::linalg::{Matrix, BaseMatrix}; use rusty_machine::learning::k_means::KMeansClassifier; use rusty_machine::learning::UnSupModel; use rand::thread_rng; -use rand::distributions::IndependentSample; -use rand::distributions::normal::Normal; +use rand_distr::{Distribution, Normal}; fn generate_data(centroids: &Matrix, points_per_centroid: usize, @@ -20,7 +20,7 @@ fn generate_data(centroids: &Matrix, centroids.cols()); let mut rng = thread_rng(); - let normal_rv = Normal::new(0f64, noise); + let normal_rv = Normal::new(0f64, noise).unwrap(); for _ in 0..points_per_centroid { // Generate points from each centroid @@ -28,7 +28,7 @@ fn generate_data(centroids: &Matrix, // Generate a point randomly around the centroid let mut point = Vec::with_capacity(centroids.cols()); for feature in centroid.iter() { - point.push(feature + normal_rv.ind_sample(&mut rng)); + point.push(feature + normal_rv.sample(&mut rng)); } // Push point to raw_cluster_data diff --git a/examples/naive_bayes_dogs.rs b/examples/naive_bayes_dogs.rs index 8a4c45cc..b792d96a 100644 --- a/examples/naive_bayes_dogs.rs +++ b/examples/naive_bayes_dogs.rs @@ -1,9 +1,9 @@ extern crate rusty_machine; extern crate rand; +extern crate rand_distr; -use rand::Rand; -use rand::distributions::Sample; -use rand::distributions::normal::Normal; +use rand::SeedableRng; +use rand_distr::{Distribution, Normal}; use rusty_machine::learning::naive_bayes::{self, NaiveBayes}; use rusty_machine::linalg::{Matrix, BaseMatrix}; use rusty_machine::learning::SupModel; @@ -23,18 +23,18 @@ struct Dog { speed: f64, } -impl Rand for Dog { +impl Dog { /// Generate a random dog. - fn rand(rng: &mut R) -> Self { + fn gen_rand(rng: &mut R) -> Self { // Friendliness, furriness, and speed are normally distributed and // (given color:) independent. - let mut red_dog_friendliness = Normal::new(0., 1.); - let mut red_dog_furriness = Normal::new(0., 1.); - let mut red_dog_speed = Normal::new(0., 1.); + let mut red_dog_friendliness = Normal::new(0., 1.).unwrap(); + let mut red_dog_furriness = Normal::new(0., 1.).unwrap(); + let mut red_dog_speed = Normal::new(0., 1.).unwrap(); - let mut white_dog_friendliness = Normal::new(1., 1.); - let mut white_dog_furriness = Normal::new(1., 1.); - let mut white_dog_speed = Normal::new(-1., 1.); + let mut white_dog_friendliness = Normal::new(1., 1.).unwrap(); + let mut white_dog_furriness = Normal::new(1., 1.).unwrap(); + let mut white_dog_speed = Normal::new(-1., 1.).unwrap(); // Flip a coin to decide whether to generate a red or white dog. let coin: f64 = rng.gen(); @@ -64,19 +64,18 @@ impl Rand for Dog { fn generate_dog_data(training_set_size: u32, test_set_size: u32) -> (Matrix, Matrix, Matrix, Vec) { - let mut randomness = rand::StdRng::new() - .expect("we should be able to get an RNG"); + let mut randomness = rand::rngs::StdRng::seed_from_u64(0); let rng = &mut randomness; // We'll train the model on these dogs let training_dogs = (0..training_set_size) - .map(|_| { Dog::rand(rng) }) + .map(|_| { Dog::gen_rand(rng) }) .collect::>(); // ... and then use the model to make predictions about these dogs' color // given only their trait measurements. let test_dogs = (0..test_set_size) - .map(|_| { Dog::rand(rng) }) + .map(|_| { Dog::gen_rand(rng) }) .collect::>(); // The model's `.train` method will take two matrices, each with a row for @@ -138,11 +137,11 @@ fn main() { for (dog, prediction) in test_dogs.iter().zip(predictions.row_iter()).take(unprinted_total) { evaluate_prediction(&mut hits, dog, prediction.raw_slice()); } - + if unprinted_total > 0 { println!("..."); } - + for (dog, prediction) in test_dogs.iter().zip(predictions.row_iter()).skip(unprinted_total) { let (actual_color, accurate) = evaluate_prediction(&mut hits, dog, prediction.raw_slice()); println!("Predicted: {:?}; Actual: {:?}; Accurate? {:?}", diff --git a/examples/nnet-and_gate.rs b/examples/nnet-and_gate.rs index 9fd7ac5e..45bc334f 100644 --- a/examples/nnet-and_gate.rs +++ b/examples/nnet-and_gate.rs @@ -1,7 +1,9 @@ extern crate rusty_machine; extern crate rand; +extern crate rand_distr; -use rand::{random, Closed01}; +use rand::{Rng, thread_rng}; +use rand_distr::OpenClosed01; use std::vec::Vec; use rusty_machine::learning::nnet::{NeuralNet, BCECriterion}; @@ -26,8 +28,8 @@ fn main() { for _ in 0..SAMPLES { // The two inputs are "signals" between 0 and 1 - let Closed01(left) = random::>(); - let Closed01(right) = random::>(); + let left: f64 = thread_rng().sample(OpenClosed01); + let right: f64 = thread_rng().sample(OpenClosed01); input_data.push(left); input_data.push(right); if left > THRESHOLD && right > THRESHOLD { diff --git a/src/data/transforms/shuffle.rs b/src/data/transforms/shuffle.rs index 445769ae..dd13e0e2 100644 --- a/src/data/transforms/shuffle.rs +++ b/src/data/transforms/shuffle.rs @@ -50,11 +50,12 @@ impl Shuffler { /// /// use rusty_machine::data::transforms::Transformer; /// use rusty_machine::data::transforms::shuffle::Shuffler; - /// use rand::{StdRng, SeedableRng}; + /// use rand::SeedableRng; + /// use rand::rngs::StdRng; /// /// # fn main() { /// // We can create a seeded rng - /// let rng = StdRng::from_seed(&[1, 2, 3]); + /// let rng = StdRng::seed_from_u64(123); /// /// let shuffler = Shuffler::new(rng); /// # } @@ -95,11 +96,12 @@ mod tests { use super::super::Transformer; use super::Shuffler; - use rand::{StdRng, SeedableRng}; + use rand::SeedableRng; + use rand::rngs::StdRng; #[test] fn seeded_shuffle() { - let rng = StdRng::from_seed(&[1, 2, 3]); + let rng = StdRng::seed_from_u64(123); let mut shuffler = Shuffler::new(rng); let mat = Matrix::new(4, 2, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]); diff --git a/src/lib.rs b/src/lib.rs index e117551b..bc760146 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -111,6 +111,7 @@ extern crate rulinalg; extern crate num as libnum; extern crate rand; +extern crate rand_distr; pub mod prelude; diff --git a/src/stats/dist/exponential.rs b/src/stats/dist/exponential.rs index 03a6ff77..db0aa27b 100644 --- a/src/stats/dist/exponential.rs +++ b/src/stats/dist/exponential.rs @@ -4,10 +4,9 @@ //! found in the rand crate. This is provided through //! traits added within the containing stats module. -use stats::dist::Distribution; +use stats::dist::Distribution as StatDistribution; use rand::Rng; -use rand::distributions::{Sample, IndependentSample}; -use rand::distributions::exponential::Exp1; +use rand_distr::{Distribution, Exp1}; /// An Exponential random variable. #[derive(Debug, Clone, Copy)] @@ -39,7 +38,7 @@ impl Exponential { } } -impl Distribution for Exponential { +impl StatDistribution for Exponential { /// The pdf of the exponential distribution. /// /// # Examples @@ -102,15 +101,9 @@ impl Distribution for Exponential { } } -impl Sample for Exponential { - fn sample(&mut self, rng: &mut R) -> f64 { - self.ind_sample(rng) - } -} - -impl IndependentSample for Exponential { - fn ind_sample(&self, rng: &mut R) -> f64 { - let Exp1(n) = rng.gen::(); +impl Distribution for Exponential { + fn sample(&self, rng: &mut R) -> f64 { + let n: f64 = rng.sample(Exp1); n / self.lambda } } diff --git a/src/stats/dist/gaussian.rs b/src/stats/dist/gaussian.rs index 8ba7f2fe..813bd698 100644 --- a/src/stats/dist/gaussian.rs +++ b/src/stats/dist/gaussian.rs @@ -4,10 +4,9 @@ //! found in the rand crate. This is provided through //! traits added within the containing stats module. -use stats::dist::Distribution; +use stats::dist::Distribution as StatDistribution; use rand::Rng; -use rand::distributions::{Sample, IndependentSample}; -use rand::distributions::normal::StandardNormal; +use rand_distr::{Distribution, StandardNormal}; use super::consts as stat_consts; use std::f64::consts as float_consts; @@ -68,7 +67,7 @@ impl Gaussian { /// /// Accurately computes the PDF and log PDF. /// Estimates the CDF accurate only to 0.003. -impl Distribution for Gaussian { +impl StatDistribution for Gaussian { /// The pdf of the normal distribution /// /// # Examples @@ -147,15 +146,9 @@ impl Distribution for Gaussian { } } -impl Sample for Gaussian { - fn sample(&mut self, rng: &mut R) -> f64 { - self.ind_sample(rng) - } -} - -impl IndependentSample for Gaussian { - fn ind_sample(&self, rng: &mut R) -> f64 { - let StandardNormal(n) = rng.gen::(); +impl Distribution for Gaussian { + fn sample(&self, rng: &mut R) -> f64 { + let n: f64 = rng.sample(StandardNormal); self.mean + self._std_dev * n } } diff --git a/tests/learning/pca.rs b/tests/learning/pca.rs index f603a768..364e7b35 100644 --- a/tests/learning/pca.rs +++ b/tests/learning/pca.rs @@ -124,4 +124,4 @@ fn test_wide() { let exp = Matrix::new(1, 2, vec![-6.550335224256381, 1.517487926775624]); assert_matrix_eq!(outputs, exp, comp=abs, tol=1e-8); -} \ No newline at end of file +}