diff --git a/src/distribution/weibull.rs b/src/distribution/weibull.rs index 1382998c..2d3a8a87 100644 --- a/src/distribution/weibull.rs +++ b/src/distribution/weibull.rs @@ -350,216 +350,181 @@ impl Continuous for Weibull { #[rustfmt::skip] #[cfg(test)] mod tests { - use crate::statistics::*; use crate::distribution::{ContinuousCDF, Continuous, Weibull}; use crate::distribution::internal::*; + use crate::statistics::*; + use crate::testing_boiler; - fn try_create(shape: f64, scale: f64) -> Weibull { - let n = Weibull::new(shape, scale); - assert!(n.is_ok()); - n.unwrap() - } - - fn create_case(shape: f64, scale: f64) { - let n = try_create(shape, scale); - assert_eq!(shape, n.shape()); - assert_eq!(scale, n.scale()); - } - - fn bad_create_case(shape: f64, scale: f64) { - let n = Weibull::new(shape, scale); - assert!(n.is_err()); - } - - fn get_value(shape: f64, scale: f64, eval: F) -> f64 - where F: Fn(Weibull) -> f64 - { - let n = try_create(shape, scale); - eval(n) - } - - fn test_case(shape: f64, scale: f64, expected: f64, eval: F) - where F: Fn(Weibull) -> f64 - { - let x = get_value(shape, scale, eval); - assert_eq!(expected, x); - } - - fn test_almost(shape: f64, scale: f64, expected: f64, acc: f64, eval: F) - where F: Fn(Weibull) -> f64 - { - let x = get_value(shape, scale, eval); - assert_almost_eq!(expected, x, acc); - } + testing_boiler!(shape: f64, scale: f64; Weibull); #[test] fn test_create() { - create_case(1.0, 0.1); - create_case(10.0, 1.0); - create_case(11.0, 10.0); - create_case(12.0, f64::INFINITY); + create_ok(1.0, 0.1); + create_ok(10.0, 1.0); + create_ok(11.0, 10.0); + create_ok(12.0, f64::INFINITY); } #[test] fn test_bad_create() { - bad_create_case(f64::NAN, 1.0); - bad_create_case(1.0, f64::NAN); - bad_create_case(f64::NAN, f64::NAN); - bad_create_case(1.0, -1.0); - bad_create_case(-1.0, 1.0); - bad_create_case(-1.0, -1.0); - bad_create_case(0.0, 0.0); - bad_create_case(0.0, 1.0); - bad_create_case(1.0, 0.0); + create_err(f64::NAN, 1.0); + create_err(1.0, f64::NAN); + create_err(f64::NAN, f64::NAN); + create_err(1.0, -1.0); + create_err(-1.0, 1.0); + create_err(-1.0, -1.0); + create_err(0.0, 0.0); + create_err(0.0, 1.0); + create_err(1.0, 0.0); } #[test] fn test_mean() { let mean = |x: Weibull| x.mean().unwrap(); - test_case(1.0, 0.1, 0.1, mean); - test_case(1.0, 1.0, 1.0, mean); - test_almost(10.0, 10.0, 9.5135076986687318362924871772654021925505786260884, 1e-14, mean); - test_almost(10.0, 1.0, 0.95135076986687318362924871772654021925505786260884, 1e-15, mean); + test_exact(1.0, 0.1, 0.1, mean); + test_exact(1.0, 1.0, 1.0, mean); + test_absolute(10.0, 10.0, 9.5135076986687318362924871772654021925505786260884, 1e-14, mean); + test_absolute(10.0, 1.0, 0.95135076986687318362924871772654021925505786260884, 1e-15, mean); } #[test] fn test_variance() { let variance = |x: Weibull| x.variance().unwrap(); - test_almost(1.0, 0.1, 0.01, 1e-16, variance); - test_almost(1.0, 1.0, 1.0, 1e-14, variance); - test_almost(10.0, 10.0, 1.3100455073468309147154581687505295026863354547057, 1e-12, variance); - test_almost(10.0, 1.0, 0.013100455073468309147154581687505295026863354547057, 1e-14, variance); + test_absolute(1.0, 0.1, 0.01, 1e-16, variance); + test_absolute(1.0, 1.0, 1.0, 1e-14, variance); + test_absolute(10.0, 10.0, 1.3100455073468309147154581687505295026863354547057, 1e-12, variance); + test_absolute(10.0, 1.0, 0.013100455073468309147154581687505295026863354547057, 1e-14, variance); } #[test] fn test_entropy() { let entropy = |x: Weibull| x.entropy().unwrap(); - test_almost(1.0, 0.1, -1.302585092994045684018, 1e-15, entropy); - test_case(1.0, 1.0, 1.0, entropy); - test_case(10.0, 10.0, 1.519494098411379574546, entropy); - test_almost(10.0, 1.0, -0.783090994582666109472, 1e-15, entropy); + test_absolute(1.0, 0.1, -1.302585092994045684018, 1e-15, entropy); + test_exact(1.0, 1.0, 1.0, entropy); + test_exact(10.0, 10.0, 1.519494098411379574546, entropy); + test_absolute(10.0, 1.0, -0.783090994582666109472, 1e-15, entropy); } #[test] fn test_skewnewss() { let skewness = |x: Weibull| x.skewness().unwrap(); - test_almost(1.0, 0.1, 2.0, 1e-13, skewness); - test_almost(1.0, 1.0, 2.0, 1e-13, skewness); - test_almost(10.0, 10.0, -0.63763713390314440916597757156663888653981696212127, 1e-11, skewness); - test_almost(10.0, 1.0, -0.63763713390314440916597757156663888653981696212127, 1e-11, skewness); + test_absolute(1.0, 0.1, 2.0, 1e-13, skewness); + test_absolute(1.0, 1.0, 2.0, 1e-13, skewness); + test_absolute(10.0, 10.0, -0.63763713390314440916597757156663888653981696212127, 1e-11, skewness); + test_absolute(10.0, 1.0, -0.63763713390314440916597757156663888653981696212127, 1e-11, skewness); } #[test] fn test_median() { let median = |x: Weibull| x.median(); - test_case(1.0, 0.1, 0.069314718055994530941723212145817656807550013436026, median); - test_case(1.0, 1.0, 0.69314718055994530941723212145817656807550013436026, median); - test_case(10.0, 10.0, 9.6401223546778973665856033763604752124634905617583, median); - test_case(10.0, 1.0, 0.96401223546778973665856033763604752124634905617583, median); + test_exact(1.0, 0.1, 0.069314718055994530941723212145817656807550013436026, median); + test_exact(1.0, 1.0, 0.69314718055994530941723212145817656807550013436026, median); + test_exact(10.0, 10.0, 9.6401223546778973665856033763604752124634905617583, median); + test_exact(10.0, 1.0, 0.96401223546778973665856033763604752124634905617583, median); } #[test] fn test_mode() { let mode = |x: Weibull| x.mode().unwrap(); - test_case(1.0, 0.1, 0.0, mode); - test_case(1.0, 1.0, 0.0, mode); - test_case(10.0, 10.0, 9.8951925820621439264623017041980483215553841533709, mode); - test_case(10.0, 1.0, 0.98951925820621439264623017041980483215553841533709, mode); + test_exact(1.0, 0.1, 0.0, mode); + test_exact(1.0, 1.0, 0.0, mode); + test_exact(10.0, 10.0, 9.8951925820621439264623017041980483215553841533709, mode); + test_exact(10.0, 1.0, 0.98951925820621439264623017041980483215553841533709, mode); } #[test] fn test_min_max() { let min = |x: Weibull| x.min(); let max = |x: Weibull| x.max(); - test_case(1.0, 1.0, 0.0, min); - test_case(1.0, 1.0, f64::INFINITY, max); + test_exact(1.0, 1.0, 0.0, min); + test_exact(1.0, 1.0, f64::INFINITY, max); } #[test] fn test_pdf() { let pdf = |arg: f64| move |x: Weibull| x.pdf(arg); - test_case(1.0, 0.1, 10.0, pdf(0.0)); - test_case(1.0, 0.1, 0.00045399929762484851535591515560550610237918088866565, pdf(1.0)); - test_case(1.0, 0.1, 3.7200759760208359629596958038631183373588922923768e-43, pdf(10.0)); - test_case(1.0, 1.0, 1.0, pdf(0.0)); - test_case(1.0, 1.0, 0.36787944117144232159552377016146086744581113103177, pdf(1.0)); - test_case(1.0, 1.0, 0.000045399929762484851535591515560550610237918088866565, pdf(10.0)); - test_case(10.0, 10.0, 0.0, pdf(0.0)); - test_almost(10.0, 10.0, 9.9999999990000000000499999999983333333333750000000e-10, 1e-24, pdf(1.0)); - test_case(10.0, 10.0, 0.36787944117144232159552377016146086744581113103177, pdf(10.0)); - test_case(10.0, 1.0, 0.0, pdf(0.0)); - test_case(10.0, 1.0, 3.6787944117144232159552377016146086744581113103177, pdf(1.0)); - test_case(10.0, 1.0, 0.0, pdf(10.0)); + test_exact(1.0, 0.1, 10.0, pdf(0.0)); + test_exact(1.0, 0.1, 0.00045399929762484851535591515560550610237918088866565, pdf(1.0)); + test_exact(1.0, 0.1, 3.7200759760208359629596958038631183373588922923768e-43, pdf(10.0)); + test_exact(1.0, 1.0, 1.0, pdf(0.0)); + test_exact(1.0, 1.0, 0.36787944117144232159552377016146086744581113103177, pdf(1.0)); + test_exact(1.0, 1.0, 0.000045399929762484851535591515560550610237918088866565, pdf(10.0)); + test_exact(10.0, 10.0, 0.0, pdf(0.0)); + test_absolute(10.0, 10.0, 9.9999999990000000000499999999983333333333750000000e-10, 1e-24, pdf(1.0)); + test_exact(10.0, 10.0, 0.36787944117144232159552377016146086744581113103177, pdf(10.0)); + test_exact(10.0, 1.0, 0.0, pdf(0.0)); + test_exact(10.0, 1.0, 3.6787944117144232159552377016146086744581113103177, pdf(1.0)); + test_exact(10.0, 1.0, 0.0, pdf(10.0)); } #[test] fn test_ln_pdf() { let ln_pdf = |arg: f64| move |x: Weibull| x.ln_pdf(arg); - test_almost(1.0, 0.1, 2.3025850929940456840179914546843642076011014886288, 1e-15, ln_pdf(0.0)); - test_almost(1.0, 0.1, -7.6974149070059543159820085453156357923988985113712, 1e-15, ln_pdf(1.0)); - test_case(1.0, 0.1, -97.697414907005954315982008545315635792398898511371, ln_pdf(10.0)); - test_case(1.0, 1.0, 0.0, ln_pdf(0.0)); - test_case(1.0, 1.0, -1.0, ln_pdf(1.0)); - test_case(1.0, 1.0, -10.0, ln_pdf(10.0)); - test_case(10.0, 10.0, f64::NEG_INFINITY, ln_pdf(0.0)); - test_almost(10.0, 10.0, -20.723265837046411156161923092159277868409913397659, 1e-14, ln_pdf(1.0)); - test_case(10.0, 10.0, -1.0, ln_pdf(10.0)); - test_case(10.0, 1.0, f64::NEG_INFINITY, ln_pdf(0.0)); - test_almost(10.0, 1.0, 1.3025850929940456840179914546843642076011014886288, 1e-15, ln_pdf(1.0)); - test_case(10.0, 1.0, -9.999999976974149070059543159820085453156357923988985113712e9, ln_pdf(10.0)); + test_absolute(1.0, 0.1, 2.3025850929940456840179914546843642076011014886288, 1e-15, ln_pdf(0.0)); + test_absolute(1.0, 0.1, -7.6974149070059543159820085453156357923988985113712, 1e-15, ln_pdf(1.0)); + test_exact(1.0, 0.1, -97.697414907005954315982008545315635792398898511371, ln_pdf(10.0)); + test_exact(1.0, 1.0, 0.0, ln_pdf(0.0)); + test_exact(1.0, 1.0, -1.0, ln_pdf(1.0)); + test_exact(1.0, 1.0, -10.0, ln_pdf(10.0)); + test_exact(10.0, 10.0, f64::NEG_INFINITY, ln_pdf(0.0)); + test_absolute(10.0, 10.0, -20.723265837046411156161923092159277868409913397659, 1e-14, ln_pdf(1.0)); + test_exact(10.0, 10.0, -1.0, ln_pdf(10.0)); + test_exact(10.0, 1.0, f64::NEG_INFINITY, ln_pdf(0.0)); + test_absolute(10.0, 1.0, 1.3025850929940456840179914546843642076011014886288, 1e-15, ln_pdf(1.0)); + test_exact(10.0, 1.0, -9.999999976974149070059543159820085453156357923988985113712e9, ln_pdf(10.0)); } #[test] fn test_cdf() { let cdf = |arg: f64| move |x: Weibull| x.cdf(arg); - test_case(1.0, 0.1, 0.0, cdf(0.0)); - test_case(1.0, 0.1, 0.99995460007023751514846440848443944938976208191113, cdf(1.0)); - test_case(1.0, 0.1, 0.99999999999999999999999999999999999999999996279924, cdf(10.0)); - test_case(1.0, 1.0, 0.0, cdf(0.0)); - test_case(1.0, 1.0, 0.63212055882855767840447622983853913255418886896823, cdf(1.0)); - test_case(1.0, 1.0, 0.99995460007023751514846440848443944938976208191113, cdf(10.0)); - test_case(10.0, 10.0, 0.0, cdf(0.0)); - test_almost(10.0, 10.0, 9.9999999995000000000166666666662500000000083333333e-11, 1e-25, cdf(1.0)); - test_case(10.0, 10.0, 0.63212055882855767840447622983853913255418886896823, cdf(10.0)); - test_case(10.0, 1.0, 0.0, cdf(0.0)); - test_case(10.0, 1.0, 0.63212055882855767840447622983853913255418886896823, cdf(1.0)); - test_case(10.0, 1.0, 1.0, cdf(10.0)); + test_exact(1.0, 0.1, 0.0, cdf(0.0)); + test_exact(1.0, 0.1, 0.99995460007023751514846440848443944938976208191113, cdf(1.0)); + test_exact(1.0, 0.1, 0.99999999999999999999999999999999999999999996279924, cdf(10.0)); + test_exact(1.0, 1.0, 0.0, cdf(0.0)); + test_exact(1.0, 1.0, 0.63212055882855767840447622983853913255418886896823, cdf(1.0)); + test_exact(1.0, 1.0, 0.99995460007023751514846440848443944938976208191113, cdf(10.0)); + test_exact(10.0, 10.0, 0.0, cdf(0.0)); + test_absolute(10.0, 10.0, 9.9999999995000000000166666666662500000000083333333e-11, 1e-25, cdf(1.0)); + test_exact(10.0, 10.0, 0.63212055882855767840447622983853913255418886896823, cdf(10.0)); + test_exact(10.0, 1.0, 0.0, cdf(0.0)); + test_exact(10.0, 1.0, 0.63212055882855767840447622983853913255418886896823, cdf(1.0)); + test_exact(10.0, 1.0, 1.0, cdf(10.0)); } #[test] fn test_sf() { let sf = |arg: f64| move |x: Weibull| x.sf(arg); - test_case(1.0, 0.1, 1.0, sf(0.0)); - test_case(1.0, 0.1, 4.5399929762484854e-5, sf(1.0)); - test_case(1.0, 0.1, 3.720075976020836e-44, sf(10.0)); - test_case(1.0, 1.0, 1.0, sf(0.0)); - test_case(1.0, 1.0, 0.36787944117144233, sf(1.0)); - test_case(1.0, 1.0, 4.5399929762484854e-5, sf(10.0)); - test_case(10.0, 10.0, 1.0, sf(0.0)); - test_almost(10.0, 10.0, 0.9999999999, 1e-25, sf(1.0)); - test_case(10.0, 10.0, 0.36787944117144233, sf(10.0)); - test_case(10.0, 1.0, 1.0, sf(0.0)); - test_case(10.0, 1.0, 0.36787944117144233, sf(1.0)); - test_case(10.0, 1.0, 0.0, sf(10.0)); + test_exact(1.0, 0.1, 1.0, sf(0.0)); + test_exact(1.0, 0.1, 4.5399929762484854e-5, sf(1.0)); + test_exact(1.0, 0.1, 3.720075976020836e-44, sf(10.0)); + test_exact(1.0, 1.0, 1.0, sf(0.0)); + test_exact(1.0, 1.0, 0.36787944117144233, sf(1.0)); + test_exact(1.0, 1.0, 4.5399929762484854e-5, sf(10.0)); + test_exact(10.0, 10.0, 1.0, sf(0.0)); + test_absolute(10.0, 10.0, 0.9999999999, 1e-25, sf(1.0)); + test_exact(10.0, 10.0, 0.36787944117144233, sf(10.0)); + test_exact(10.0, 1.0, 1.0, sf(0.0)); + test_exact(10.0, 1.0, 0.36787944117144233, sf(1.0)); + test_exact(10.0, 1.0, 0.0, sf(10.0)); } #[test] fn test_inverse_cdf() { let func = |arg: f64| move |x: Weibull| x.inverse_cdf(x.cdf(arg)); - test_case(1.0, 0.1, 0.0, func(0.0)); - test_almost(1.0, 0.1, 1.0, 1e-13, func(1.0)); - test_case(1.0, 1.0, 0.0, func(0.0)); - test_case(1.0, 1.0, 1.0, func(1.0)); - test_almost(1.0, 1.0, 10.0, 1e-10, func(10.0)); - test_case(10.0, 10.0, 0.0, func(0.0)); - test_almost(10.0, 10.0, 1.0, 1e-5, func(1.0)); - test_almost(10.0, 10.0, 10.0, 1e-10, func(10.0)); - test_case(10.0, 1.0, 0.0, func(0.0)); - test_case(10.0, 1.0, 1.0, func(1.0)); + test_exact(1.0, 0.1, 0.0, func(0.0)); + test_absolute(1.0, 0.1, 1.0, 1e-13, func(1.0)); + test_exact(1.0, 1.0, 0.0, func(0.0)); + test_exact(1.0, 1.0, 1.0, func(1.0)); + test_absolute(1.0, 1.0, 10.0, 1e-10, func(10.0)); + test_exact(10.0, 10.0, 0.0, func(0.0)); + test_absolute(10.0, 10.0, 1.0, 1e-5, func(1.0)); + test_absolute(10.0, 10.0, 10.0, 1e-10, func(10.0)); + test_exact(10.0, 1.0, 0.0, func(0.0)); + test_exact(10.0, 1.0, 1.0, func(1.0)); } #[test] fn test_continuous() { - test::check_continuous_distribution(&try_create(1.0, 0.2), 0.0, 10.0); + test::check_continuous_distribution(&create_ok(1.0, 0.2), 0.0, 10.0); } }