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}