rand_simple/distributions/
weibull.rs

1use crate::create_state;
2use crate::standard_distributions::standard_exponential;
3
4/// Weibull Distribution
5/// # Example
6/// ```
7/// let mut weibull = rand_simple::Weibull::new(1192u32);
8/// assert_eq!(format!("{weibull}"), "Weibull(Shape parameter, Scale parameter) = Weibull(1, 1)");
9///
10/// // If you want to change the parameters of the random variable
11/// let shape: f64 = 2f64;
12/// let scale: f64 = 1.5f64;
13/// let result: Result<(f64, f64), &str> = weibull.try_set_params(shape, scale);
14/// assert_eq!(format!("{weibull}"), "Weibull(Shape parameter, Scale parameter) = Weibull(2, 1.5)");
15/// ```
16pub struct Weibull {
17    xyzuv: [u32; 5], // 状態変数
18    shape: f64,      // 形状母数
19    scale: f64,      // 尺度母数
20}
21
22impl Weibull {
23    /// Constructor for the Weibull random number generator.
24    /// * `_seed` - Seed for the random number generator.
25    pub fn new(_seed: u32) -> Self {
26        // Create a new instance of the Weibull random number generator with the specified seed,
27        // and default shape and scale parameters set to 1.0.
28        Self {
29            xyzuv: create_state(_seed),
30            shape: 1_f64,
31            scale: 1_f64,
32        }
33    }
34
35    /// Computes a random number.
36    /// Returns a random number sampled from the Weibull distribution with the specified shape and scale parameters.
37    pub fn sample(&mut self) -> f64 {
38        loop {
39            // Generate a random number from the standard exponential distribution.
40            let z = standard_exponential(&mut self.xyzuv);
41
42            // Check if the generated number is greater than 0.
43            if z > 0_f64 {
44                // Calculate the random number from the Weibull distribution using the generated value.
45                return z.powf(self.shape.powi(-1)) * self.scale;
46            }
47        }
48    }
49
50    /// Attempts to set the parameters of the probability variable.
51    /// * `shape` - Shape parameter.
52    /// * `scale` - Scale parameter.
53    ///   Returns a Result containing a tuple (shape, scale) on success, or an error message if the parameters are invalid.
54    pub fn try_set_params(&mut self, shape: f64, scale: f64) -> Result<(f64, f64), &str> {
55        // Check if the shape or scale parameters are non-positive, and return an error if so.
56        if shape <= 0_f64 || scale <= 0_f64 {
57            Err("Shape or scale parameter is less than or equal to 0. Parameters will be maintained from the previous setting.")
58        } else {
59            // Set the shape and scale parameters and return a tuple (shape, scale).
60            self.shape = shape;
61            self.scale = scale;
62            Ok((shape, scale))
63        }
64    }
65}
66
67// Implementation of the Display trait for the Weibull struct, allowing custom formatting when using format! or println!
68impl core::fmt::Display for Weibull {
69    /// Implements the Display trait for the Weibull struct.
70    /// This allows the struct to be formatted and displayed using macros like println!
71    /// It displays information about the scale parameter.
72    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
73        write!(
74            f,
75            "Weibull(Shape parameter, Scale parameter) = Weibull({}, {})",
76            self.shape, self.scale
77        )?;
78        Ok(())
79    }
80}