diff --git a/Cargo.toml b/Cargo.toml index 5626ab84..cd3125e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ keywords = ["probability", "statistics", "stats", "distribution", "math"] categories = ["science"] homepage = "https://github.com/statrs-dev/statrs" repository = "https://github.com/statrs-dev/statrs" -edition = "2021" +edition = "2024" include = ["CHANGELOG.md", "LICENSE.md", "src/", "tests/"] diff --git a/benches/order_statistics.rs b/benches/order_statistics.rs index eb7d6582..d86f9f9d 100644 --- a/benches/order_statistics.rs +++ b/benches/order_statistics.rs @@ -1,5 +1,5 @@ extern crate statrs; -use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion}; +use criterion::{BatchSize, Criterion, black_box, criterion_group, criterion_main}; use rand::prelude::*; use statrs::statistics::*; diff --git a/src/distribution/bernoulli.rs b/src/distribution/bernoulli.rs index e9928209..a04ee25b 100644 --- a/src/distribution/bernoulli.rs +++ b/src/distribution/bernoulli.rs @@ -111,11 +111,7 @@ impl DiscreteCDF for Bernoulli { /// else { 1 - p } /// ``` fn cdf(&self, x: u64) -> f64 { - if x >= 1 { - 1. - } else { - 1. - self.b.p() - } + if x >= 1 { 1. } else { 1. - self.b.p() } } /// Calculates the survival function for the diff --git a/src/distribution/binomial.rs b/src/distribution/binomial.rs index 6fd7e014..f4eec3b5 100644 --- a/src/distribution/binomial.rs +++ b/src/distribution/binomial.rs @@ -117,11 +117,7 @@ impl ::rand::distr::Distribution for Binomial { fn sample(&self, rng: &mut R) -> u64 { (0..self.n).fold(0, |acc, _| { let n: f64 = rng.random(); - if n < self.p { - acc + 1 - } else { - acc - } + if n < self.p { acc + 1 } else { acc } }) } } @@ -304,17 +300,9 @@ impl Discrete for Binomial { if x > self.n { 0.0 } else if self.p == 0.0 { - if x == 0 { - 1.0 - } else { - 0.0 - } + if x == 0 { 1.0 } else { 0.0 } } else if prec::ulps_eq!(self.p, 1.0) { - if x == self.n { - 1.0 - } else { - 0.0 - } + if x == self.n { 1.0 } else { 0.0 } } else { (factorial::ln_binomial(self.n, x) + x as f64 * self.p.ln() @@ -335,17 +323,9 @@ impl Discrete for Binomial { if x > self.n { f64::NEG_INFINITY } else if self.p == 0.0 { - if x == 0 { - 0.0 - } else { - f64::NEG_INFINITY - } + if x == 0 { 0.0 } else { f64::NEG_INFINITY } } else if prec::ulps_eq!(self.p, 1.0) { - if x == self.n { - 0.0 - } else { - f64::NEG_INFINITY - } + if x == self.n { 0.0 } else { f64::NEG_INFINITY } } else { factorial::ln_binomial(self.n, x) + x as f64 * self.p.ln() diff --git a/src/distribution/dirac.rs b/src/distribution/dirac.rs index 5d42238b..0db6dedf 100644 --- a/src/distribution/dirac.rs +++ b/src/distribution/dirac.rs @@ -97,11 +97,7 @@ impl ContinuousCDF for Dirac { /// /// Where the value is 1 if x > `v`, 0 otherwise. fn cdf(&self, x: f64) -> f64 { - if x < self.0 { - 0.0 - } else { - 1.0 - } + if x < self.0 { 0.0 } else { 1.0 } } /// Calculates the survival function for the @@ -109,11 +105,7 @@ impl ContinuousCDF for Dirac { /// /// Where the value is 0 if x > `v`, 1 otherwise. fn sf(&self, x: f64) -> f64 { - if x < self.0 { - 1.0 - } else { - 0.0 - } + if x < self.0 { 1.0 } else { 0.0 } } } diff --git a/src/distribution/discrete_uniform.rs b/src/distribution/discrete_uniform.rs index 099b15fe..21d14bed 100644 --- a/src/distribution/discrete_uniform.rs +++ b/src/distribution/discrete_uniform.rs @@ -147,11 +147,7 @@ impl DiscreteCDF for DiscreteUniform { let lower = self.min as f64; let upper = self.max as f64; let ans = (x as f64 - lower + 1.0) / (upper - lower + 1.0); - if ans > 1.0 { - 1.0 - } else { - ans - } + if ans > 1.0 { 1.0 } else { ans } } } @@ -165,11 +161,7 @@ impl DiscreteCDF for DiscreteUniform { let lower = self.min as f64; let upper = self.max as f64; let ans = (upper - x as f64) / (upper - lower + 1.0); - if ans > 1.0 { - 1.0 - } else { - ans - } + if ans > 1.0 { 1.0 } else { ans } } } } diff --git a/src/distribution/empirical.rs b/src/distribution/empirical.rs index b1357d39..99f1bd99 100644 --- a/src/distribution/empirical.rs +++ b/src/distribution/empirical.rs @@ -20,11 +20,7 @@ mod non_nan { impl NonNan { #[inline] pub fn new(x: f64) -> Option { - if x.is_nan() { - None - } else { - Some(Self(x)) - } + if x.is_nan() { None } else { Some(Self(x)) } } } diff --git a/src/distribution/exponential.rs b/src/distribution/exponential.rs index b7a0436e..278770ae 100644 --- a/src/distribution/exponential.rs +++ b/src/distribution/exponential.rs @@ -131,11 +131,7 @@ impl ContinuousCDF for Exp { /// /// where `λ` is the rate fn sf(&self, x: f64) -> f64 { - if x < 0.0 { - 1.0 - } else { - (-self.rate * x).exp() - } + if x < 0.0 { 1.0 } else { (-self.rate * x).exp() } } /// Calculates the inverse cumulative distribution function. diff --git a/src/distribution/laplace.rs b/src/distribution/laplace.rs index 85bb45e6..12c4da36 100644 --- a/src/distribution/laplace.rs +++ b/src/distribution/laplace.rs @@ -133,11 +133,7 @@ impl ContinuousCDF for Laplace { /// where `μ` is the location, `b` is the scale fn cdf(&self, x: f64) -> f64 { let y = (-(x - self.location).abs() / self.scale).exp() / 2.; - if x >= self.location { - 1. - y - } else { - y - } + if x >= self.location { 1. - y } else { y } } /// Calculates the survival function for the @@ -152,11 +148,7 @@ impl ContinuousCDF for Laplace { /// where `μ` is the location, `b` is the scale fn sf(&self, x: f64) -> f64 { let y = (-(x - self.location).abs() / self.scale).exp() / 2.; - if x >= self.location { - y - } else { - 1. - y - } + if x >= self.location { y } else { 1. - y } } /// Calculates the inverse cumulative distribution function for the diff --git a/src/distribution/multinomial.rs b/src/distribution/multinomial.rs index 052476a2..d21791aa 100644 --- a/src/distribution/multinomial.rs +++ b/src/distribution/multinomial.rs @@ -310,13 +310,12 @@ where return 0.0; } let coeff = factorial::multinomial(self.n, x.as_slice()); - let val = coeff + coeff * self .p .iter() .zip(x.iter()) - .fold(1.0, |acc, (pi, xi)| acc * pi.powf(*xi as f64)); - val + .fold(1.0, |acc, (pi, xi)| acc * pi.powf(*xi as f64)) } /// Calculates the log probability mass function for the multinomial @@ -345,14 +344,14 @@ where return f64::NEG_INFINITY; } let coeff = factorial::multinomial(self.n, x.as_slice()).ln(); - let val = coeff + + coeff + self .p .iter() .zip(x.iter()) .map(|(pi, xi)| *xi as f64 * pi.ln()) - .fold(0.0, |acc, x| acc + x); - val + .fold(0.0, |acc, x| acc + x) } } diff --git a/src/distribution/students_t.rs b/src/distribution/students_t.rs index 530ea4f5..1d0da476 100644 --- a/src/distribution/students_t.rs +++ b/src/distribution/students_t.rs @@ -183,11 +183,7 @@ impl ContinuousCDF for StudentsT { let k = (x - self.location) / self.scale; let h = self.freedom / (self.freedom + k * k); let ib = 0.5 * beta::beta_reg(self.freedom / 2.0, 0.5, h); - if x <= self.location { - ib - } else { - 1.0 - ib - } + if x <= self.location { ib } else { 1.0 - ib } } } @@ -215,11 +211,7 @@ impl ContinuousCDF for StudentsT { let k = (x - self.location) / self.scale; let h = self.freedom / (self.freedom + k * k); let ib = 0.5 * beta::beta_reg(self.freedom / 2.0, 0.5, h); - if x <= self.location { - 1.0 - ib - } else { - ib - } + if x <= self.location { 1.0 - ib } else { ib } } } @@ -357,11 +349,7 @@ impl Distribution for StudentsT { /// 0 /// ``` fn skewness(&self) -> Option { - if self.freedom <= 3.0 { - None - } else { - Some(0.0) - } + if self.freedom <= 3.0 { None } else { Some(0.0) } } } diff --git a/src/distribution/ziggurat.rs b/src/distribution/ziggurat.rs index 0524aa35..589e23ab 100644 --- a/src/distribution/ziggurat.rs +++ b/src/distribution/ziggurat.rs @@ -1,6 +1,6 @@ use super::ziggurat_tables; -use rand::distr::Open01; use rand::Rng; +use rand::distr::Open01; pub fn sample_std_normal(rng: &mut R) -> f64 { #[inline] diff --git a/src/function/beta.rs b/src/function/beta.rs index 6f157071..ba9eab0f 100644 --- a/src/function/beta.rs +++ b/src/function/beta.rs @@ -421,11 +421,7 @@ pub fn inv_beta_reg(mut a: f64, mut b: f64, mut x: f64) -> f64 { qprev = q; } - if flip { - 1.0 - p - } else { - p - } + if flip { 1.0 - p } else { p } } #[cfg(test)] diff --git a/src/function/gamma.rs b/src/function/gamma.rs index 1f4b79b9..db47a814 100644 --- a/src/function/gamma.rs +++ b/src/function/gamma.rs @@ -435,11 +435,7 @@ pub fn inv_digamma(x: f64) -> f64 { // by inv_digamma, may consider extracting into a public // method fn signum(x: f64) -> f64 { - if x == 0.0 { - 0.0 - } else { - x.signum() - } + if x == 0.0 { 0.0 } else { x.signum() } } #[rustfmt::skip] diff --git a/src/statistics/iter_statistics.rs b/src/statistics/iter_statistics.rs index 57a723a3..552e2f22 100644 --- a/src/statistics/iter_statistics.rs +++ b/src/statistics/iter_statistics.rs @@ -12,11 +12,7 @@ where match iter.next() { None => f64::NAN, Some(x) => iter.map(|x| *x.borrow()).fold(*x.borrow(), |acc, x| { - if x < acc || x.is_nan() { - x - } else { - acc - } + if x < acc || x.is_nan() { x } else { acc } }), } } @@ -26,11 +22,7 @@ where match iter.next() { None => f64::NAN, Some(x) => iter.map(|x| *x.borrow()).fold(*x.borrow(), |acc, x| { - if x > acc || x.is_nan() { - x - } else { - acc - } + if x > acc || x.is_nan() { x } else { acc } }), } } @@ -42,11 +34,7 @@ where Some(init) => iter .map(|x| x.borrow().abs()) .fold(init.borrow().abs(), |acc, x| { - if x < acc || x.is_nan() { - x - } else { - acc - } + if x < acc || x.is_nan() { x } else { acc } }), } } @@ -58,11 +46,7 @@ where Some(init) => iter .map(|x| x.borrow().abs()) .fold(init.borrow().abs(), |acc, x| { - if x > acc || x.is_nan() { - x - } else { - acc - } + if x > acc || x.is_nan() { x } else { acc } }), } } @@ -74,11 +58,7 @@ where i += 1.0; mean += (x.borrow() - mean) / i; } - if i > 0.0 { - mean - } else { - f64::NAN - } + if i > 0.0 { mean } else { f64::NAN } } fn geometric_mean(self) -> f64 { @@ -88,11 +68,7 @@ where i += 1.0; sum += x.borrow().ln(); } - if i > 0.0 { - (sum / i).exp() - } else { - f64::NAN - } + if i > 0.0 { (sum / i).exp() } else { f64::NAN } } fn harmonic_mean(self) -> f64 { @@ -107,11 +83,7 @@ where } sum += 1.0 / borrow; } - if i > 0.0 { - i / sum - } else { - f64::NAN - } + if i > 0.0 { i / sum } else { f64::NAN } } fn variance(self) -> f64 { @@ -216,11 +188,7 @@ where if iter.next().is_some() { panic!("Iterators must have the same length") } - if n > 0.0 { - comoment / n - } else { - f64::NAN - } + if n > 0.0 { comoment / n } else { f64::NAN } } fn quadratic_mean(self) -> f64 { @@ -231,11 +199,7 @@ where i += 1.0; mean += (borrow * borrow - mean) / i; } - if i > 0.0 { - mean.sqrt() - } else { - f64::NAN - } + if i > 0.0 { mean.sqrt() } else { f64::NAN } } } diff --git a/src/stats_tests/chisquare.rs b/src/stats_tests/chisquare.rs index 1ec9216f..16d247c7 100644 --- a/src/stats_tests/chisquare.rs +++ b/src/stats_tests/chisquare.rs @@ -27,7 +27,10 @@ impl core::fmt::Display for ChiSquareTestError { write!(f, "`f_exp` must have same length and sum as `f_obs`") } ChiSquareTestError::DdofInvalid => { - write!(f, "for the p-value to be meaningful, `ddof` must be at least two less than the number of categories, k, which is the length of `f_obs`") + write!( + f, + "for the p-value to be meaningful, `ddof` must be at least two less than the number of categories, k, which is the length of `f_obs`" + ) } } } diff --git a/src/stats_tests/fisher.rs b/src/stats_tests/fisher.rs index 78d76175..b055929a 100644 --- a/src/stats_tests/fisher.rs +++ b/src/stats_tests/fisher.rs @@ -13,13 +13,7 @@ fn binary_search( epsilon: f64, upper: bool, ) -> u64 { - let (mut min_val, mut max_val) = { - if upper { - (mode, n) - } else { - (0, mode) - } - }; + let (mut min_val, mut max_val) = { if upper { (mode, n) } else { (0, mode) } }; let population = n1 + n2; let successes = n1; @@ -39,13 +33,7 @@ fn binary_search( } }; - let ng = { - if upper { - guess - 1 - } else { - guess + 1 - } - }; + let ng = { if upper { guess - 1 } else { guess + 1 } }; let pmf_comp = dist.pmf(ng); let p_guess = dist.pmf(guess); @@ -109,7 +97,10 @@ impl core::fmt::Display for FishersExactTestError { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { match self { FishersExactTestError::TableInvalidForHypergeometric(hg_err) => { - writeln!(f, "Cannot create a Hypergeometric distribution from the data in the contingency table.")?; + writeln!( + f, + "Cannot create a Hypergeometric distribution from the data in the contingency table." + )?; writeln!(f, "Is it in row-major order?")?; write!(f, "Inner error: '{hg_err}'") } diff --git a/src/stats_tests/ks_test.rs b/src/stats_tests/ks_test.rs index fdb63114..c054ec2e 100644 --- a/src/stats_tests/ks_test.rs +++ b/src/stats_tests/ks_test.rs @@ -38,8 +38,14 @@ impl core::fmt::Display for KSTestError { "samples can not contain NaN when nan_policy is set to NaNPolicy::Error" ) } - KSTestError::ExactAndTies => write!(f, "`KSOneSampleAlternativeMethod::TwoSidedExact`selected with ties in data"), - KSTestError::ExactAndTooLarge => write!(f, "`KSOneSampleAlternativeMethod::TwoSidedExact`selected with the size of the data (`n`) being too large"), + KSTestError::ExactAndTies => write!( + f, + "`KSOneSampleAlternativeMethod::TwoSidedExact`selected with ties in data" + ), + KSTestError::ExactAndTooLarge => write!( + f, + "`KSOneSampleAlternativeMethod::TwoSidedExact`selected with the size of the data (`n`) being too large" + ), } } }