From 666f5dac4eba920a1ba17042f3f14a316dbbf00d Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Tue, 28 May 2024 17:27:18 +0200 Subject: [PATCH 1/2] add `random` to `inbreeding` to draw elements --- bins/inbreeding/src/main.rs | 1 + bins/inbreeding/src/random.rs | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 bins/inbreeding/src/random.rs diff --git a/bins/inbreeding/src/main.rs b/bins/inbreeding/src/main.rs index 71beb012..212b0cae 100644 --- a/bins/inbreeding/src/main.rs +++ b/bins/inbreeding/src/main.rs @@ -12,6 +12,7 @@ use komodo::{ use rand::{rngs::StdRng, seq::SliceRandom, Rng, RngCore, SeedableRng}; mod environment; +mod random; mod strategy; use crate::{environment::Environment, strategy::Strategy}; diff --git a/bins/inbreeding/src/random.rs b/bins/inbreeding/src/random.rs new file mode 100644 index 00000000..8593049f --- /dev/null +++ b/bins/inbreeding/src/random.rs @@ -0,0 +1,25 @@ +use rand::{Rng, RngCore}; +use std::collections::HashSet; + +fn draw_unique_indices(n: usize, vec_len: usize, rng: &mut impl RngCore) -> HashSet<usize> { + let mut indices = HashSet::new(); + + while indices.len() < n { + let idx = rng.gen_range(0..vec_len); + indices.insert(idx); + } + + indices +} + +pub(super) fn draw_unique_elements<T: Clone>( + things: &[T], + n: usize, + rng: &mut impl RngCore, +) -> Vec<T> { + let mut res = vec![]; + for i in draw_unique_indices(n, things.len(), rng) { + res.push(things[i].clone()); + } + res +} -- GitLab From 57c7e9b1b7da5817e1ab7cde869c6cd8f7206031 Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Tue, 28 May 2024 17:27:43 +0200 Subject: [PATCH 2/2] use `draw_unique_elements` to draw shards --- bins/inbreeding/src/environment.rs | 27 ++++++++++++--------------- bins/inbreeding/src/main.rs | 8 +++----- bins/inbreeding/src/strategy.rs | 9 ++++----- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/bins/inbreeding/src/environment.rs b/bins/inbreeding/src/environment.rs index 2b1feaeb..11357823 100644 --- a/bins/inbreeding/src/environment.rs +++ b/bins/inbreeding/src/environment.rs @@ -1,4 +1,6 @@ -use rand::{seq::SliceRandom, Rng, RngCore}; +use rand::{Rng, RngCore}; + +use crate::random::draw_unique_elements; #[derive(Debug, PartialEq)] pub(super) enum Environment { @@ -14,28 +16,23 @@ impl Environment { /// `update(things, rng)` is `things` with some elements potentially removed according to the /// [`Environment`] type pub(super) fn update<T: Clone>(&self, things: &[T], rng: &mut impl RngCore) -> Vec<T> { - let mut things = things.to_vec(); - things.shuffle(rng); - - match self { - Environment::Fixed { n } => things.iter().take(things.len() - n), + let nb_to_take = match self { + Environment::Fixed { n } => things.len() - n, Environment::RandomFixed { p, n } => { if rng.gen::<f64>() > *p { - return things; + return things.to_vec(); } - things.iter().take(things.len() - n) + things.len() - n } Environment::RandomDynamic { p, q } => { if rng.gen::<f64>() > *p { - return things; + return things.to_vec(); } - things - .iter() - .take((things.len() as f64 * (1.0 - q)) as usize) + (things.len() as f64 * (1.0 - q)) as usize } - } - .cloned() - .collect() + }; + + draw_unique_elements(things, nb_to_take, rng) } pub(super) fn from_str(s: &str) -> Result<Self, String> { diff --git a/bins/inbreeding/src/main.rs b/bins/inbreeding/src/main.rs index 212b0cae..51f2d08b 100644 --- a/bins/inbreeding/src/main.rs +++ b/bins/inbreeding/src/main.rs @@ -9,7 +9,8 @@ use komodo::{ fec::{self, Shard}, linalg::Matrix, }; -use rand::{rngs::StdRng, seq::SliceRandom, Rng, RngCore, SeedableRng}; +use rand::{rngs::StdRng, Rng, RngCore, SeedableRng}; +use random::draw_unique_elements; mod environment; mod random; @@ -39,16 +40,13 @@ fn measure_inbreeding<F: PrimeField>( sty: &ProgressStyle, rng: &mut impl RngCore, ) -> f64 { - let mut s: Vec<_> = shards.to_vec(); let mut count = 0; let pb = mp.add(ProgressBar::new(nb_measurements as u64)); pb.set_style(sty.clone()); pb.set_message("measure"); for _ in 0..nb_measurements { - // get any k of the shards - s.shuffle(rng); - if fec::decode(s.iter().take(k).cloned().collect()).is_ok() { + if fec::decode(draw_unique_elements(shards, k, rng)).is_ok() { count += 1; } pb.inc(1); diff --git a/bins/inbreeding/src/strategy.rs b/bins/inbreeding/src/strategy.rs index f8f8143e..ffe57360 100644 --- a/bins/inbreeding/src/strategy.rs +++ b/bins/inbreeding/src/strategy.rs @@ -1,4 +1,6 @@ -use rand::{seq::SliceRandom, Rng, RngCore}; +use rand::{Rng, RngCore}; + +use crate::random::draw_unique_elements; #[derive(Debug, PartialEq)] pub(super) enum Strategy { @@ -8,9 +10,6 @@ pub(super) enum Strategy { impl Strategy { pub(super) fn draw<T: Clone>(&self, things: &[T], rng: &mut impl RngCore) -> Vec<T> { - let mut things = things.to_vec(); - things.shuffle(rng); - let nb_to_take = match self { Self::Single { n } => *n, Self::Double { p, n, m } => { @@ -22,7 +21,7 @@ impl Strategy { } }; - things.iter().take(nb_to_take).cloned().collect() + draw_unique_elements(things, nb_to_take, rng) } pub(super) fn from_str(s: &str) -> Result<Self, String> { -- GitLab