warlocks_cauldron/providers/
numeric.rs

1use std::{
2    collections::{
3        hash_map::DefaultHasher,
4        HashMap,
5    },
6    hash::{Hash, Hasher},
7    cmp::Eq, sync::Mutex,
8};
9
10use num::Complex;
11use counter::Counter;
12
13use super::dependencies::*;
14
15
16lazy_static! {
17    static ref INCREMENTS: Mutex<Counter<u64>> = Mutex::new(Counter::new());
18}
19
20/// Methods collection for generate any numeric values
21pub struct Numeric;
22
23impl Numeric {
24    /// Generate incremental number
25    /// 
26    /// Each call of this method returns an incrementing number (with the step of +1)
27    pub fn increment<S: Hash>(some: S) -> usize {
28        let mut hasher = DefaultHasher::new();
29        some.hash(&mut hasher);
30        INCREMENTS.lock().unwrap()
31            .entry(hasher.finish())
32            .and_modify(|counter| *counter += 1)
33            .or_insert(1)
34            .to_owned()
35    }
36
37    /// Reset incremental number
38    /// 
39    /// Each call of this method reset linked increment value
40    pub fn reset_increment<S: Hash>(some: S) {
41        let mut hasher = DefaultHasher::new();
42        some.hash(&mut hasher);
43        INCREMENTS.lock().unwrap()
44            .entry(hasher.finish())
45            .and_modify(|counter| *counter = 0);
46    }
47
48
49    /// Reset all incremental number
50    /// 
51    /// Each call of this method reset all counter
52    pub fn reset_increments() {
53        *INCREMENTS.lock().unwrap() = Counter::new();
54    }
55
56    /// Generate random number in range [start, end]
57    pub fn number<T: rand::distributions::uniform::SampleUniform + std::cmp::PartialOrd>(start: T, end: T) -> T {
58        randint(start, end)
59    }
60
61    /// Generate random float number in range [start, end]
62    pub fn float_number(start: f32, end: f32) -> f32 {
63        uniform(start, end)
64    }
65
66    /// Generate a vector of random float numbers
67    pub fn floats(start: f32, end: f32, n: usize) -> Vec<f32> {
68        (0..n).map(|_| Self::float_number(start, end)).collect()
69    }
70
71    /// Generate random integer from start to end
72    ///
73    /// Integers can be negative or positive numbers
74    pub fn integer_number(start: i32, end: i32) -> i32 {
75        randint(start, end)
76    }
77    
78    /// Generate a vector of random integers
79    ///
80    /// Integers can be negative or positive numbers
81    pub fn integers(start: i32, end: i32, n: usize) -> Vec<i32> {
82        (0..n).map(|_| Self::integer_number(start, end)).collect()
83    }
84
85    /// Generate a random complex int number
86    pub fn complex_int_number(start_real: i32, end_real: i32, start_imag: i32, end_imag: i32) -> Complex<i32> {
87        Complex::new(randint(start_real, end_real), randint(start_imag, end_imag))
88    }
89
90    /// Generate a list of random complex int numbers
91    pub fn int_complexes(start_real: i32, end_real: i32, start_imag: i32, end_imag: i32, n: usize) -> Vec<Complex<i32>> {
92        (0..n).map(|_| Self::complex_int_number(start_real, end_real, start_imag, end_imag)).collect()
93    }
94
95    /// Generate a random complex float number
96    pub fn complex_float_number(start_real: f32, end_real: f32, start_imag: f32, end_imag: f32) -> Complex<f32> {
97        Complex::new(uniform(start_real, end_real), uniform(start_imag, end_imag))
98    }
99
100    /// Generate a list of random complex float numbers
101    pub fn float_complexes(start_real: f32, end_real: f32, start_imag: f32, end_imag: f32, n: usize) -> Vec<Complex<f32>> {
102        (0..n).map(|_| Self::complex_float_number(start_real, end_real, start_imag, end_imag)).collect()
103    }
104}