Auto merge of #136324 - GrigorenkoPV:erf, r=tgross35
Implement `f{16,32,64,128}::{erf,erfc}` (`#![feature(float_erf)]`) Tracking issue: #136321 try-job: x86_64-gnu-aux
This commit is contained in:
commit
f77247ac59
8 changed files with 295 additions and 0 deletions
|
@ -1226,6 +1226,7 @@ impl f128 {
|
|||
#[inline]
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
// #[unstable(feature = "float_gamma", issue = "99842")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub fn gamma(self) -> f128 {
|
||||
unsafe { cmath::tgammaf128(self) }
|
||||
|
@ -1260,10 +1261,83 @@ impl f128 {
|
|||
#[inline]
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
// #[unstable(feature = "float_gamma", issue = "99842")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub fn ln_gamma(self) -> (f128, i32) {
|
||||
let mut signgamp: i32 = 0;
|
||||
let x = unsafe { cmath::lgammaf128_r(self, &mut signgamp) };
|
||||
(x, signgamp)
|
||||
}
|
||||
|
||||
/// Error function.
|
||||
///
|
||||
/// # Unspecified precision
|
||||
///
|
||||
/// The precision of this function is non-deterministic. This means it varies by platform,
|
||||
/// Rust version, and can even differ within the same execution from one invocation to the next.
|
||||
///
|
||||
/// This function currently corresponds to the `erff128` from libc on Unix
|
||||
/// and Windows. Note that this might change in the future.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// #![feature(float_erf)]
|
||||
/// # #[cfg(reliable_f128_math)] {
|
||||
/// /// The error function relates what percent of a normal distribution lies
|
||||
/// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
|
||||
/// fn within_standard_deviations(x: f128) -> f128 {
|
||||
/// (x * std::f128::consts::FRAC_1_SQRT_2).erf() * 100.0
|
||||
/// }
|
||||
///
|
||||
/// // 68% of a normal distribution is within one standard deviation
|
||||
/// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.01);
|
||||
/// // 95% of a normal distribution is within two standard deviations
|
||||
/// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.01);
|
||||
/// // 99.7% of a normal distribution is within three standard deviations
|
||||
/// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.01);
|
||||
/// # }
|
||||
/// ```
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
// #[unstable(feature = "float_erf", issue = "136321")]
|
||||
#[inline]
|
||||
pub fn erf(self) -> f128 {
|
||||
unsafe { cmath::erff128(self) }
|
||||
}
|
||||
|
||||
/// Complementary error function.
|
||||
///
|
||||
/// # Unspecified precision
|
||||
///
|
||||
/// The precision of this function is non-deterministic. This means it varies by platform,
|
||||
/// Rust version, and can even differ within the same execution from one invocation to the next.
|
||||
///
|
||||
/// This function currently corresponds to the `erfcf128` from libc on Unix
|
||||
/// and Windows. Note that this might change in the future.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// #![feature(float_erf)]
|
||||
/// # #[cfg(reliable_f128_math)] {
|
||||
/// let x: f128 = 0.123;
|
||||
///
|
||||
/// let one = x.erf() + x.erfc();
|
||||
/// let abs_difference = (one - 1.0).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f128::EPSILON);
|
||||
/// # }
|
||||
/// ```
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
// #[unstable(feature = "float_erf", issue = "136321")]
|
||||
#[inline]
|
||||
pub fn erfc(self) -> f128 {
|
||||
unsafe { cmath::erfcf128(self) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1224,6 +1224,7 @@ impl f16 {
|
|||
#[inline]
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
// #[unstable(feature = "float_gamma", issue = "99842")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub fn gamma(self) -> f16 {
|
||||
(unsafe { cmath::tgammaf(self as f32) }) as f16
|
||||
|
@ -1258,10 +1259,81 @@ impl f16 {
|
|||
#[inline]
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
// #[unstable(feature = "float_gamma", issue = "99842")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub fn ln_gamma(self) -> (f16, i32) {
|
||||
let mut signgamp: i32 = 0;
|
||||
let x = (unsafe { cmath::lgammaf_r(self as f32, &mut signgamp) }) as f16;
|
||||
(x, signgamp)
|
||||
}
|
||||
|
||||
/// Error function.
|
||||
///
|
||||
/// # Unspecified precision
|
||||
///
|
||||
/// The precision of this function is non-deterministic. This means it varies by platform,
|
||||
/// Rust version, and can even differ within the same execution from one invocation to the next.
|
||||
///
|
||||
/// This function currently corresponds to the `erff` from libc on Unix
|
||||
/// and Windows. Note that this might change in the future.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f16)]
|
||||
/// #![feature(float_erf)]
|
||||
/// # #[cfg(reliable_f16_math)] {
|
||||
/// /// The error function relates what percent of a normal distribution lies
|
||||
/// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
|
||||
/// fn within_standard_deviations(x: f16) -> f16 {
|
||||
/// (x * std::f16::consts::FRAC_1_SQRT_2).erf() * 100.0
|
||||
/// }
|
||||
///
|
||||
/// // 68% of a normal distribution is within one standard deviation
|
||||
/// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.1);
|
||||
/// // 95% of a normal distribution is within two standard deviations
|
||||
/// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.1);
|
||||
/// // 99.7% of a normal distribution is within three standard deviations
|
||||
/// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.1);
|
||||
/// # }
|
||||
/// ```
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
// #[unstable(feature = "float_erf", issue = "136321")]
|
||||
#[inline]
|
||||
pub fn erf(self) -> f16 {
|
||||
(unsafe { cmath::erff(self as f32) }) as f16
|
||||
}
|
||||
|
||||
/// Complementary error function.
|
||||
///
|
||||
/// # Unspecified precision
|
||||
///
|
||||
/// The precision of this function is non-deterministic. This means it varies by platform,
|
||||
/// Rust version, and can even differ within the same execution from one invocation to the next.
|
||||
///
|
||||
/// This function currently corresponds to the `erfcf` from libc on Unix
|
||||
/// and Windows. Note that this might change in the future.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f16)]
|
||||
/// #![feature(float_erf)]
|
||||
/// let x: f16 = 0.123;
|
||||
///
|
||||
/// let one = x.erf() + x.erfc();
|
||||
/// let abs_difference = (one - 1.0).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f16::EPSILON);
|
||||
/// ```
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
// #[unstable(feature = "float_erf", issue = "136321")]
|
||||
#[inline]
|
||||
pub fn erfc(self) -> f16 {
|
||||
(unsafe { cmath::erfcf(self as f32) }) as f16
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1151,4 +1151,68 @@ impl f32 {
|
|||
let x = unsafe { cmath::lgammaf_r(self, &mut signgamp) };
|
||||
(x, signgamp)
|
||||
}
|
||||
|
||||
/// Error function.
|
||||
///
|
||||
/// # Unspecified precision
|
||||
///
|
||||
/// The precision of this function is non-deterministic. This means it varies by platform,
|
||||
/// Rust version, and can even differ within the same execution from one invocation to the next.
|
||||
///
|
||||
/// This function currently corresponds to the `erff` from libc on Unix
|
||||
/// and Windows. Note that this might change in the future.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(float_erf)]
|
||||
/// /// The error function relates what percent of a normal distribution lies
|
||||
/// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
|
||||
/// fn within_standard_deviations(x: f32) -> f32 {
|
||||
/// (x * std::f32::consts::FRAC_1_SQRT_2).erf() * 100.0
|
||||
/// }
|
||||
///
|
||||
/// // 68% of a normal distribution is within one standard deviation
|
||||
/// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.01);
|
||||
/// // 95% of a normal distribution is within two standard deviations
|
||||
/// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.01);
|
||||
/// // 99.7% of a normal distribution is within three standard deviations
|
||||
/// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.01);
|
||||
/// ```
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[unstable(feature = "float_erf", issue = "136321")]
|
||||
#[inline]
|
||||
pub fn erf(self) -> f32 {
|
||||
unsafe { cmath::erff(self) }
|
||||
}
|
||||
|
||||
/// Complementary error function.
|
||||
///
|
||||
/// # Unspecified precision
|
||||
///
|
||||
/// The precision of this function is non-deterministic. This means it varies by platform,
|
||||
/// Rust version, and can even differ within the same execution from one invocation to the next.
|
||||
///
|
||||
/// This function currently corresponds to the `erfcf` from libc on Unix
|
||||
/// and Windows. Note that this might change in the future.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(float_erf)]
|
||||
/// let x: f32 = 0.123;
|
||||
///
|
||||
/// let one = x.erf() + x.erfc();
|
||||
/// let abs_difference = (one - 1.0).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f32::EPSILON);
|
||||
/// ```
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[unstable(feature = "float_erf", issue = "136321")]
|
||||
#[inline]
|
||||
pub fn erfc(self) -> f32 {
|
||||
unsafe { cmath::erfcf(self) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1151,4 +1151,68 @@ impl f64 {
|
|||
let x = unsafe { cmath::lgamma_r(self, &mut signgamp) };
|
||||
(x, signgamp)
|
||||
}
|
||||
|
||||
/// Error function.
|
||||
///
|
||||
/// # Unspecified precision
|
||||
///
|
||||
/// The precision of this function is non-deterministic. This means it varies by platform,
|
||||
/// Rust version, and can even differ within the same execution from one invocation to the next.
|
||||
///
|
||||
/// This function currently corresponds to the `erf` from libc on Unix
|
||||
/// and Windows. Note that this might change in the future.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(float_erf)]
|
||||
/// /// The error function relates what percent of a normal distribution lies
|
||||
/// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
|
||||
/// fn within_standard_deviations(x: f64) -> f64 {
|
||||
/// (x * std::f64::consts::FRAC_1_SQRT_2).erf() * 100.0
|
||||
/// }
|
||||
///
|
||||
/// // 68% of a normal distribution is within one standard deviation
|
||||
/// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.01);
|
||||
/// // 95% of a normal distribution is within two standard deviations
|
||||
/// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.01);
|
||||
/// // 99.7% of a normal distribution is within three standard deviations
|
||||
/// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.01);
|
||||
/// ```
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[unstable(feature = "float_erf", issue = "136321")]
|
||||
#[inline]
|
||||
pub fn erf(self) -> f64 {
|
||||
unsafe { cmath::erf(self) }
|
||||
}
|
||||
|
||||
/// Complementary error function.
|
||||
///
|
||||
/// # Unspecified precision
|
||||
///
|
||||
/// The precision of this function is non-deterministic. This means it varies by platform,
|
||||
/// Rust version, and can even differ within the same execution from one invocation to the next.
|
||||
///
|
||||
/// This function currently corresponds to the `erfc` from libc on Unix
|
||||
/// and Windows. Note that this might change in the future.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(float_erf)]
|
||||
/// let x: f64 = 0.123;
|
||||
///
|
||||
/// let one = x.erf() + x.erfc();
|
||||
/// let abs_difference = (one - 1.0).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f64::EPSILON);
|
||||
/// ```
|
||||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[unstable(feature = "float_erf", issue = "136321")]
|
||||
#[inline]
|
||||
pub fn erfc(self) -> f64 {
|
||||
unsafe { cmath::erfc(self) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,10 @@ unsafe extern "C" {
|
|||
pub fn lgamma_r(n: f64, s: &mut i32) -> f64;
|
||||
#[cfg(not(target_os = "aix"))]
|
||||
pub fn lgammaf_r(n: f32, s: &mut i32) -> f32;
|
||||
pub fn erf(n: f64) -> f64;
|
||||
pub fn erff(n: f32) -> f32;
|
||||
pub fn erfc(n: f64) -> f64;
|
||||
pub fn erfcf(n: f32) -> f32;
|
||||
|
||||
pub fn acosf128(n: f128) -> f128;
|
||||
pub fn asinf128(n: f128) -> f128;
|
||||
|
@ -43,6 +47,8 @@ unsafe extern "C" {
|
|||
pub fn tanhf128(n: f128) -> f128;
|
||||
pub fn tgammaf128(n: f128) -> f128;
|
||||
pub fn lgammaf128_r(n: f128, s: &mut i32) -> f128;
|
||||
pub fn erff128(n: f128) -> f128;
|
||||
pub fn erfcf128(n: f128) -> f128;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(all(target_os = "windows", target_env = "msvc", target_arch = "x86")))] {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue