// Copyright 2018 Developers of the Rand project. // Copyright 2016-2017 The Rust Project Developers. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms.
//! The Cauchy distribution.
use num_traits::{Float, FloatConst}; usecrate::{Distribution, Standard}; use rand::Rng; use core::fmt;
/// The Cauchy distribution `Cauchy(median, scale)`. /// /// This distribution has a density function: /// `f(x) = 1 / (pi * scale * (1 + ((x - median) / scale)^2))` /// /// Note that at least for `f32`, results are not fully portable due to minor /// differences in the target system's *tan* implementation, `tanf`. /// /// # Example /// /// ``` /// use rand_distr::{Cauchy, Distribution}; /// /// let cau = Cauchy::new(2.0, 5.0).unwrap(); /// let v = cau.sample(&mut rand::thread_rng()); /// println!("{} is from a Cauchy(2, 5) distribution", v); /// ``` #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] pubstruct Cauchy<F> where F: Float + FloatConst, Standard: Distribution<F>
{
median: F,
scale: F,
}
/// Error type returned from `Cauchy::new`. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pubenum Error { /// `scale <= 0` or `nan`.
ScaleTooSmall,
}
impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(matchself {
Error::ScaleTooSmall => "scale is not positive in Cauchy distribution",
})
}
}
impl<F> Cauchy<F> where F: Float + FloatConst, Standard: Distribution<F>
{ /// Construct a new `Cauchy` with the given shape parameters /// `median` the peak location and `scale` the scale factor. pubfn new(median: F, scale: F) -> Result<Cauchy<F>, Error> { if !(scale > F::zero()) { return Err(Error::ScaleTooSmall);
}
Ok(Cauchy { median, scale })
}
}
impl<F> Distribution<F> for Cauchy<F> where F: Float + FloatConst, Standard: Distribution<F>
{ fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> F { // sample from [0, 1) let x = Standard.sample(rng); // get standard cauchy random number // note that π/2 is not exactly representable, even if x=0.5 the result is finite let comp_dev = (F::PI() * x).tan(); // shift and scale according to parameters self.median + self.scale * comp_dev
}
}
#[test] fn test_cauchy_averages() { // NOTE: given that the variance and mean are undefined, // this test does not have any rigorous statistical meaning. let cauchy = Cauchy::new(10.0, 5.0).unwrap(); letmut rng = crate::test::rng(123); letmut numbers: [f64; 1000] = [0.0; 1000]; letmut sum = 0.0; for number in &mut numbers[..] {
*number = cauchy.sample(&mut rng);
sum += *number;
} let median = median(&mut numbers); #[cfg(feature = "std")]
std::println!("Cauchy median: {}", median);
assert!((median - 10.0).abs() < 0.4); // not 100% certain, but probable enough let mean = sum / 1000.0; #[cfg(feature = "std")]
std::println!("Cauchy mean: {}", mean); // for a Cauchy distribution the mean should not converge
assert!((mean - 10.0).abs() > 0.4); // not 100% certain, but probable enough
}
// Unfortunately this test is not fully portable due to reliance on the // system's implementation of tanf (see doc on Cauchy struct). letmut buf = [0.0; 4];
gen_samples(10f32, 7.0, &mut buf); let expected = [15.023088, -5.446413, 3.7092876, 3.112482]; for (a, b) in buf.iter().zip(expected.iter()) {
assert_almost_eq!(*a, *b, 1e-5);
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.