From 9f2cc3d973f538e1171b0b6b74edfe416650b2ee Mon Sep 17 00:00:00 2001 From: Adam Kern Date: Sun, 16 Mar 2025 18:30:41 -0400 Subject: [PATCH 1/4] Bump rand to 0.9.0 and rand_distr to 0.5.0 --- Cargo.toml | 4 ++-- ndarray-rand/benches/bench.rs | 2 +- ndarray-rand/src/lib.rs | 15 ++++++++------- ndarray-rand/tests/tests.rs | 14 +++++++------- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3d1c1dde6..98326a598 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,8 +96,8 @@ num-traits = { version = "0.2", default-features = false } num-complex = { version = "0.4", default-features = false } approx = { version = "0.5", default-features = false } quickcheck = { version = "1.0", default-features = false } -rand = { version = "0.8.0", features = ["small_rng"] } -rand_distr = { version = "0.4.0" } +rand = { version = "0.9.0", features = ["small_rng"] } +rand_distr = { version = "0.5.0" } itertools = { version = "0.13.0", default-features = false, features = ["use_std"] } cblas-sys = { version = "0.1.4", default-features = false } diff --git a/ndarray-rand/benches/bench.rs b/ndarray-rand/benches/bench.rs index 0e5eb2ff7..364eca9f4 100644 --- a/ndarray-rand/benches/bench.rs +++ b/ndarray-rand/benches/bench.rs @@ -13,7 +13,7 @@ use test::Bencher; fn uniform_f32(b: &mut Bencher) { let m = 100; - b.iter(|| Array::random((m, m), Uniform::new(-1f32, 1.))); + b.iter(|| Array::random((m, m), Uniform::new(-1f32, 1.).unwrap())); } #[bench] diff --git a/ndarray-rand/src/lib.rs b/ndarray-rand/src/lib.rs index 6671ab334..8309067a8 100644 --- a/ndarray-rand/src/lib.rs +++ b/ndarray-rand/src/lib.rs @@ -29,10 +29,10 @@ //! that the items are not compatible (e.g. that a type doesn't implement a //! necessary trait). -use crate::rand::distributions::{Distribution, Uniform}; +use crate::rand::distr::{Distribution, Uniform}; use crate::rand::rngs::SmallRng; use crate::rand::seq::index; -use crate::rand::{thread_rng, Rng, SeedableRng}; +use crate::rand::{rng, Rng, SeedableRng}; use ndarray::{Array, Axis, RemoveAxis, ShapeBuilder}; use ndarray::{ArrayBase, Data, DataOwned, Dimension, RawData}; @@ -71,8 +71,8 @@ where /// Create an array with shape `dim` with elements drawn from /// `distribution` using the default RNG. /// - /// ***Panics*** if creation of the RNG fails or if the number of elements - /// overflows usize. + /// ***Panics*** if creation of the RNG fails, the number of elements + /// overflows usize, or the axis has zero length. /// /// ``` /// use ndarray::Array; @@ -95,7 +95,8 @@ where /// Create an array with shape `dim` with elements drawn from /// `distribution`, using a specific Rng `rng`. /// - /// ***Panics*** if the number of elements overflows usize. + /// ***Panics*** if the number of elements overflows usize + /// or the axis has zero length. /// /// ``` /// use ndarray::Array; @@ -270,7 +271,7 @@ where { let indices: Vec<_> = match strategy { SamplingStrategy::WithReplacement => { - let distribution = Uniform::from(0..self.len_of(axis)); + let distribution = Uniform::new(0, self.len_of(axis)).unwrap(); (0..n_samples).map(|_| distribution.sample(rng)).collect() } SamplingStrategy::WithoutReplacement => index::sample(rng, self.len_of(axis), n_samples).into_vec(), @@ -308,5 +309,5 @@ impl Arbitrary for SamplingStrategy fn get_rng() -> SmallRng { - SmallRng::from_rng(thread_rng()).expect("create SmallRng from thread_rng failed") + SmallRng::from_rng(&mut rng()) } diff --git a/ndarray-rand/tests/tests.rs b/ndarray-rand/tests/tests.rs index d38e8636e..d17bc8924 100644 --- a/ndarray-rand/tests/tests.rs +++ b/ndarray-rand/tests/tests.rs @@ -13,7 +13,7 @@ fn test_dim() let (mm, nn) = (5, 5); for m in 0..mm { for n in 0..nn { - let a = Array::random((m, n), Uniform::new(0., 2.)); + let a = Array::random((m, n), Uniform::new(0., 2.).unwrap()); assert_eq!(a.shape(), &[m, n]); assert!(a.iter().all(|x| *x < 2.)); assert!(a.iter().all(|x| *x >= 0.)); @@ -28,7 +28,7 @@ fn test_dim_f() let (mm, nn) = (5, 5); for m in 0..mm { for n in 0..nn { - let a = Array::random((m, n).f(), Uniform::new(0., 2.)); + let a = Array::random((m, n).f(), Uniform::new(0., 2.).unwrap()); assert_eq!(a.shape(), &[m, n]); assert!(a.iter().all(|x| *x < 2.)); assert!(a.iter().all(|x| *x >= 0.)); @@ -41,7 +41,7 @@ fn test_dim_f() fn sample_axis_on_view() { let m = 5; - let a = Array::random((m, 4), Uniform::new(0., 2.)); + let a = Array::random((m, 4), Uniform::new(0., 2.).unwrap()); let _samples = a .view() .sample_axis(Axis(0), m, SamplingStrategy::WithoutReplacement); @@ -52,7 +52,7 @@ fn sample_axis_on_view() fn oversampling_without_replacement_should_panic() { let m = 5; - let a = Array::random((m, 4), Uniform::new(0., 2.)); + let a = Array::random((m, 4), Uniform::new(0., 2.).unwrap()); let _samples = a.sample_axis(Axis(0), m + 1, SamplingStrategy::WithoutReplacement); } @@ -60,7 +60,7 @@ quickcheck! { #[cfg_attr(miri, ignore)] // Takes an insufferably long time fn oversampling_with_replacement_is_fine(m: u8, n: u8) -> TestResult { let (m, n) = (m as usize, n as usize); - let a = Array::random((m, n), Uniform::new(0., 2.)); + let a = Array::random((m, n), Uniform::new(0., 2.).unwrap()); // Higher than the length of both axes let n_samples = m + n + 1; @@ -136,7 +136,7 @@ fn is_subset(a: &Array2, b: &ArrayView1, axis: Axis) -> bool fn sampling_without_replacement_from_a_zero_length_axis_should_panic() { let n = 5; - let a = Array::random((0, n), Uniform::new(0., 2.)); + let a = Array::random((0, n), Uniform::new(0., 2.).unwrap()); let _samples = a.sample_axis(Axis(0), 1, SamplingStrategy::WithoutReplacement); } @@ -145,6 +145,6 @@ fn sampling_without_replacement_from_a_zero_length_axis_should_panic() fn sampling_with_replacement_from_a_zero_length_axis_should_panic() { let n = 5; - let a = Array::random((0, n), Uniform::new(0., 2.)); + let a = Array::random((0, n), Uniform::new(0., 2.).unwrap()); let _samples = a.sample_axis(Axis(0), 1, SamplingStrategy::WithReplacement); } From f98c8fe3162301fd1519bf4e8308be0d4bb52290 Mon Sep 17 00:00:00 2001 From: Adam Kern Date: Sun, 16 Mar 2025 18:43:20 -0400 Subject: [PATCH 2/4] Forgot to update a test --- crates/numeric-tests/tests/accuracy.rs | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/numeric-tests/tests/accuracy.rs b/crates/numeric-tests/tests/accuracy.rs index c594f020d..db10d57cd 100644 --- a/crates/numeric-tests/tests/accuracy.rs +++ b/crates/numeric-tests/tests/accuracy.rs @@ -86,7 +86,7 @@ where #[test] fn accurate_eye_f32() { - let rng = &mut SmallRng::from_entropy(); + let rng = &mut SmallRng::from_os_rng(); for i in 0..20 { let eye = Array::eye(i); for j in 0..20 { @@ -99,8 +99,8 @@ fn accurate_eye_f32() } // pick a few random sizes for _ in 0..10 { - let i = rng.gen_range(15..512); - let j = rng.gen_range(15..512); + let i = rng.random_range(15..512); + let j = rng.random_range(15..512); println!("Testing size {} by {}", i, j); let a = gen::(Ix2(i, j), rng); let eye = Array::eye(i); @@ -114,7 +114,7 @@ fn accurate_eye_f32() #[test] fn accurate_eye_f64() { - let rng = &mut SmallRng::from_entropy(); + let rng = &mut SmallRng::from_os_rng(); let abs_tol = 1e-15; for i in 0..20 { let eye = Array::eye(i); @@ -128,8 +128,8 @@ fn accurate_eye_f64() } // pick a few random sizes for _ in 0..10 { - let i = rng.gen_range(15..512); - let j = rng.gen_range(15..512); + let i = rng.random_range(15..512); + let j = rng.random_range(15..512); println!("Testing size {} by {}", i, j); let a = gen::(Ix2(i, j), rng); let eye = Array::eye(i); @@ -172,9 +172,9 @@ fn random_matrix_mul( ) -> (Array2, Array2) where A: LinalgScalar { - let m = rng.gen_range(15..128); - let k = rng.gen_range(15..128); - let n = rng.gen_range(15..512); + let m = rng.random_range(15..128); + let k = rng.random_range(15..128); + let n = rng.random_range(15..512); let a = generator(Ix2(m, k), rng); let b = generator(Ix2(n, k), rng); let c = if use_general { @@ -209,7 +209,7 @@ where A: fmt::Debug, { // pick a few random sizes - let mut rng = SmallRng::from_entropy(); + let mut rng = SmallRng::from_os_rng(); for i in 0..20 { let (c, reference) = random_matrix_mul(&mut rng, i > 10, use_general, gen::); @@ -241,7 +241,7 @@ where A: fmt::Debug, { // pick a few random sizes - let mut rng = SmallRng::from_entropy(); + let mut rng = SmallRng::from_os_rng(); for i in 0..20 { let (c, reference) = random_matrix_mul(&mut rng, i > 10, true, gen_complex::); @@ -259,10 +259,10 @@ where fn accurate_mul_with_column_f64() { // pick a few random sizes - let rng = &mut SmallRng::from_entropy(); + let rng = &mut SmallRng::from_os_rng(); for i in 0..10 { - let m = rng.gen_range(1..128); - let k = rng.gen_range(1..350); + let m = rng.random_range(1..128); + let k = rng.random_range(1..350); let a = gen::(Ix2(m, k), rng); let b_owner = gen::(Ix2(k, k), rng); let b_row_col; From baf2295f282dd602c3fea9f9b7c1611bc3d159da Mon Sep 17 00:00:00 2001 From: Adam Kern Date: Sun, 16 Mar 2025 18:58:16 -0400 Subject: [PATCH 3/4] Also updates rand_isaac dev dependency --- ndarray-rand/Cargo.toml | 2 +- ndarray-rand/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ndarray-rand/Cargo.toml b/ndarray-rand/Cargo.toml index b58e752a5..72b959020 100644 --- a/ndarray-rand/Cargo.toml +++ b/ndarray-rand/Cargo.toml @@ -21,7 +21,7 @@ rand_distr = { workspace = true } quickcheck = { workspace = true, optional = true } [dev-dependencies] -rand_isaac = "0.3.0" +rand_isaac = "0.4.0" quickcheck = { workspace = true } [package.metadata.release] diff --git a/ndarray-rand/src/lib.rs b/ndarray-rand/src/lib.rs index 8309067a8..795e246d4 100644 --- a/ndarray-rand/src/lib.rs +++ b/ndarray-rand/src/lib.rs @@ -80,7 +80,7 @@ where /// use ndarray_rand::rand_distr::Uniform; /// /// # fn main() { - /// let a = Array::random((2, 5), Uniform::new(0., 10.)); + /// let a = Array::random((2, 5), Uniform::new(0., 10.).unwrap()); /// println!("{:8.4}", a); /// // Example Output: /// // [[ 8.6900, 6.9824, 3.8922, 6.5861, 2.4890], @@ -111,7 +111,7 @@ where /// let mut rng = Isaac64Rng::seed_from_u64(seed); /// /// // Generate a random array using `rng` - /// let a = Array::random_using((2, 5), Uniform::new(0., 10.), &mut rng); + /// let a = Array::random_using((2, 5), Uniform::new(0., 10.).unwrap(), &mut rng); /// println!("{:8.4}", a); /// // Example Output: /// // [[ 8.6900, 6.9824, 3.8922, 6.5861, 2.4890], From 5090c6bccdd400686420c009fe9ea2e9d37d24e6 Mon Sep 17 00:00:00 2001 From: Adam Kern Date: Sun, 16 Mar 2025 19:20:03 -0400 Subject: [PATCH 4/4] And the quickcheck example --- ndarray-rand/tests/tests.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ndarray-rand/tests/tests.rs b/ndarray-rand/tests/tests.rs index d17bc8924..5d322551a 100644 --- a/ndarray-rand/tests/tests.rs +++ b/ndarray-rand/tests/tests.rs @@ -1,6 +1,6 @@ use ndarray::{Array, Array2, ArrayView1, Axis}; #[cfg(feature = "quickcheck")] -use ndarray_rand::rand::{distributions::Distribution, thread_rng}; +use ndarray_rand::rand::{distr::Distribution, rng}; use ndarray::ShapeBuilder; use ndarray_rand::rand_distr::Uniform; @@ -90,12 +90,12 @@ quickcheck! { #[cfg_attr(miri, ignore)] // This takes *forever* with Miri fn sampling_behaves_as_expected(m: u8, n: u8, strategy: SamplingStrategy) -> TestResult { let (m, n) = (m as usize, n as usize); - let a = Array::random((m, n), Uniform::new(0., 2.)); - let mut rng = &mut thread_rng(); + let a = Array::random((m, n), Uniform::new(0., 2.).unwrap()); + let mut rng = &mut rng(); // We don't want to deal with sampling from 0-length axes in this test if m != 0 { - let n_row_samples = Uniform::from(1..m+1).sample(&mut rng); + let n_row_samples = Uniform::new(1, m+1).unwrap().sample(&mut rng); if !sampling_works(&a, strategy.clone(), Axis(0), n_row_samples) { return TestResult::failed(); } @@ -105,7 +105,7 @@ quickcheck! { // We don't want to deal with sampling from 0-length axes in this test if n != 0 { - let n_col_samples = Uniform::from(1..n+1).sample(&mut rng); + let n_col_samples = Uniform::new(1, n+1).unwrap().sample(&mut rng); if !sampling_works(&a, strategy, Axis(1), n_col_samples) { return TestResult::failed(); }