1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
//! Let's abstract an alloy
use rand::{distributions::WeightedIndex, prelude::Distribution, Rng};
/// An alloy is a collection of kinds of atoms and their ratios
///
/// It is used to pick a kind of atom from the alloy.
///
/// # Example
///
/// ```rust
/// use vegas_lattice::Alloy;
///
/// let alloy = Alloy::new(vec!["Fe", "Ni"], vec![1, 2]);
/// let kind = alloy.pick(&mut rand::thread_rng());
///
/// assert!(kind == "Fe" || kind == "Ni");
/// ```
#[derive(Debug)]
pub struct Alloy {
kinds: Vec<String>,
weights: WeightedIndex<u32>,
}
impl Alloy {
/// Create a new alloy with a given list of kinds and their ratios
pub fn new(kinds: Vec<&str>, ratios: Vec<u32>) -> Self {
debug_assert!(kinds.len() == ratios.len());
Self {
kinds: kinds.into_iter().map(|s| s.to_owned()).collect(),
weights: WeightedIndex::new(&ratios).unwrap(),
}
}
/// Picks a kind of atom from the alloy
pub fn pick<R: Rng + ?Sized>(&self, rng: &mut R) -> String {
self.kinds[self.weights.sample(rng)].clone()
}
}