causal_hub/random/models/graphs/
undirected.rs1use itertools::Itertools;
2use rand::{Rng, RngExt};
3
4use crate::{
5 models::{Graph, UnGraph},
6 random::Random,
7 types::{Error, Labels, Result},
8};
9
10pub struct RngUnGraph<'a, R> {
12 rng: &'a mut R,
13 labels: &'a Labels,
14 probability: f64,
15}
16
17impl<'a, R> RngUnGraph<'a, R> {
18 pub fn new(rng: &'a mut R, labels: &'a Labels, probability: f64) -> Result<Self> {
31 if !(0.0..=1.0).contains(&probability) {
33 return Err(Error::InvalidParameter("p", "must be in [0, 1]"));
34 }
35
36 Ok(Self {
37 rng,
38 labels,
39 probability,
40 })
41 }
42}
43
44impl<R: Rng> Random for RngUnGraph<'_, R> {
45 type Output = Result<UnGraph>;
46
47 fn random(&mut self) -> Self::Output {
48 let mut graph = UnGraph::empty(self.labels)?;
50
51 let n = self.labels.len();
53
54 (0..n)
56 .combinations(2)
57 .filter(|_| self.rng.random_bool(self.probability))
59 .try_for_each(|idx| -> Result<()> {
60 let (i, j) = (idx[0], idx[1]);
62 graph.add_edge(i, j)?;
63
64 Ok(())
65 })?;
66
67 Ok(graph)
68 }
69}