Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ const WRAPPER_INCLUDES: &[&str] = &[
"kelvin.h",
"lambertw.h",
"legendre.h",
"log_exp.h",
"log.h",
"loggamma.h",
"mathieu.h",
Expand Down Expand Up @@ -186,12 +185,6 @@ const WRAPPER_SPECS: &[(&str, &str)] = &[
("legendre_p", "iD->D"),
("sph_legendre_p", "iid->d"),
("sph_legendre_p", "iiD->D"),
// log_exp.h
("expit", "d->d"),
("exprel", "d->d"),
("logit", "d->d"),
("log_expit", "d->d"),
("log1mexp", "d->d"),
// log.h
("log1p", "d->d"),
("log1p", "D->D"),
Expand Down
62 changes: 31 additions & 31 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,11 @@
//!
//! ## Sigmoidal functions
//!
//! | Function | Description |
//! | -------------- | ---------------------------------------- |
//! | [`logit`] | Logit function, $\ln \( \frac{x}{1-x} \) $ |
//! | [`expit`] | Expit function, $\frac{1}{1 + \exp(-x)}$ |
//! | [`log_expit`] | Logarithm of [`expit`] |
//! | Function | Description |
//! | ------------- | ----------------------------------------- |
//! | [`logit`] | Logit function, $\ln \( \frac{x}{1-x} \)$ |
//! | [`expit`] | Expit function, $\frac{1}{1 + \exp(-x)}$ |
//! | [`log_expit`] | Logarithm of [`expit`] |
//!
//! ## Miscellaneous
//!
Expand Down Expand Up @@ -324,8 +324,8 @@
//!
//! # Parabolic cylinder functions
//!
//! | Function | Description |
//! | -------- | ---------------------------------------------- |
//! | Function | Description |
//! | -------- | ------------------------------------------------------------------ |
//! | [`pbdv`] | Parabolic cylinder function $D_v(x)$ and its derivative $D_v\'(x)$ |
//! | [`pbvv`] | Parabolic cylinder function $V_v(x)$ and its derivative $V_v\'(x)$ |
//! | [`pbwa`] | Parabolic cylinder function $W_a(x)$ and its derivative $W_a\'(x)$ |
Expand Down Expand Up @@ -370,13 +370,13 @@
//! | ---------- | ---------------- | ----------------------------------- |
//! | [`kelvin`] | [`kelvin_zeros`] | Kelvin functions as complex numbers |
//! | [`ber`] | [`ber_zeros`] | Kelvin function $\ber(x)$ |
//! | [`berp`] | [`berp_zeros`] | Derivative of [`ber`], $\ber\'(x)$ |
//! | [`berp`] | [`berp_zeros`] | Derivative of [`ber`], $\ber\'(x)$ |
//! | [`bei`] | [`bei_zeros`] | Kelvin function $\bei(x)$ |
//! | [`beip`] | [`beip_zeros`] | Derivative of [`bei`], $\bei\'(x)$ |
//! | [`beip`] | [`beip_zeros`] | Derivative of [`bei`], $\bei\'(x)$ |
//! | [`ker`] | [`ker_zeros`] | Kelvin function $\ker(x)$ |
//! | [`kerp`] | [`kerp_zeros`] | Derivative of [`ker`], $\ker\'(x)$ |
//! | [`kerp`] | [`kerp_zeros`] | Derivative of [`ker`], $\ker\'(x)$ |
//! | [`kei`] | [`kei_zeros`] | Kelvin function $\kei(x)$ |
//! | [`keip`] | [`keip_zeros`] | Derivative of [`kei`], $\kei\'(x)$ |
//! | [`keip`] | [`keip_zeros`] | Derivative of [`kei`], $\kei\'(x)$ |
//!
//! # Combinatorics
//!
Expand Down Expand Up @@ -426,29 +426,29 @@
//! | [`shichi`] | Hyperbolic sine and cosine integrals $\Shi(z)$ and $\Chi(z)$ |
//! | [`spence`] | Spence's function, also known as the dilogarithm |
//! | [`softplus`] | $\ln(1 + e^x)$ |
//! | [`log1mexp`] | $\ln(1 - e^x)$ |
//!
//! # Convenience functions
//!
//! | Function | Description |
//! | -------------- | ----------------------------------------------------- |
//! | [`cbrt`] | $\sqrt\[3\]{x}$ |
//! | [`exp10`] | $10^x$ |
//! | [`exp2`] | $2^x$ |
//! | [`radian`] | Convert from degrees to radians |
//! | [`cosdg`] | Cosine of an angle in degrees |
//! | [`sindg`] | Sine of an angle in degrees |
//! | [`tandg`] | Tangent of an angle in degrees |
//! | [`cotdg`] | Cotangent of an angle in degrees |
//! | [`log1p`] | $\ln(1+x)$ |
//! | [`expm1`] | $e^x - 1$ |
//! | [`cosm1`] | $\cos(x) - 1$ |
//! | [`round`] | Round to nearest or even integer-valued float |
//! | [`xlogy`] | $x \ln(y)$ or $0$ if $x = 0$ |
//! | [`xlog1py`] | $x \ln(1+y)$ or $0$ if $x = 0$ |
//! | [`logaddexp`] | $\ln(e^x + e^y)$ |
//! | [`logaddexp2`] | $\log_2(2^x + 2^y)$ |
//! | [`exprel`] | Relative error exponential, $e^x - 1 \over x$ |
//! | [`sinc`] | Normalized sinc function, $\sin(\pi x) \over \pi x$ |
//! | Function | Description |
//! | -------------- | --------------------------------------------------- |
//! | [`cbrt`] | $\sqrt\[3\]{x}$ |
//! | [`exp10`] | $10^x$ |
//! | [`exp2`] | $2^x$ |
//! | [`radian`] | Convert from degrees to radians |
//! | [`cosdg`] | Cosine of an angle in degrees |
//! | [`sindg`] | Sine of an angle in degrees |
//! | [`tandg`] | Tangent of an angle in degrees |
//! | [`cotdg`] | Cotangent of an angle in degrees |
//! | [`expm1`] | $e^x - 1$ |
//! | [`cosm1`] | $\cos(x) - 1$ |
//! | [`round`] | Round to nearest or even integer-valued float |
//! | [`xlogy`] | $x \ln(y)$ or $0$ if $x = 0$ |
//! | [`xlog1py`] | $x \ln(1+y)$ or $0$ if $x = 0$ |
//! | [`logaddexp`] | $\ln(e^x + e^y)$ |
//! | [`logaddexp2`] | $\log_2(2^x + 2^y)$ |
//! | [`exprel`] | Relative error exponential, $e^x - 1 \over x$ |
//! | [`sinc`] | Normalized sinc function, $\sin(\pi x) \over \pi x$ |
//!
#![warn(
Expand Down
80 changes: 70 additions & 10 deletions src/xsf/log_exp.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,96 @@
/// Expit function, `1/(1 + exp(-x))`
/// Expit (a.k.a. logistic sigmoid) function, $1 / (1 + e^{-x})$
///
/// Corresponds to [`scipy.special.expit`][expit]. Translated into pure Rust from Cephes.
///
/// [expit]: https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.expit.html
///
/// # See also
/// - [`logit`]
#[must_use]
#[inline]
pub fn expit(x: f64) -> f64 {
unsafe { crate::ffi::xsf::expit(x) }
1.0 / (1.0 + (-x).exp())
}

/// Relative error exponential, `(exp(x) - 1)/x`
/// Relative error exponential, $(e^x - 1) / x$
///
/// Corresponds to [`scipy.special.exprel`][exprel]. Translated into pure Rust from Cephes.
///
/// [exprel]: https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.exprel.html
///
/// # See also
/// - [`expm1`](crate::expm1)
#[must_use]
#[inline]
pub fn exprel(x: f64) -> f64 {
unsafe { crate::ffi::xsf::exprel(x) }
if x.abs() < f64::EPSILON {
1.0
} else if x > 717.0 {
// near f64::MAX.log()
f64::INFINITY
} else {
x.exp_m1() / x
}
}

/// Logit function, `log(x / (1 - x))`
/// Logit function, $\ln(x / (1 - x))$
///
/// Corresponds to [`scipy.special.logit`][logit]. Translated into pure Rust from Cephes.
///
/// [logit]: https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.logit.html
///
/// # See also
/// - [`expit`]
#[must_use]
#[inline]
pub fn logit(x: f64) -> f64 {
unsafe { crate::ffi::xsf::logit(x) }
// The standard formula is log(x/(1 - x)), but this expression
// loses precision near x=0.5, as does log(x) - log1p(-x).
// We use the standard formula away from p=0.5, and use
// log1p(2*(x - 0.5)) - log1p(-2*(x - 0.5)) around p=0.5, which
// provides very good precision in this interval.
if (0.3..=0.65).contains(&x) {
let s = 2.0 * (x - 0.5);
s.ln_1p() - (-s).ln_1p()
} else {
(x / (1.0 - x)).ln()
}
}

/// Log of the expit function, `log(expit(x))`
/// Natural logarithm of [`expit`]
///
/// Corresponds to [`scipy.special.expit`][expit]. Translated into pure Rust from Cephes.
///
/// [expit]: https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.expit.html
#[must_use]
#[inline]
pub fn log_expit(x: f64) -> f64 {
unsafe { crate::ffi::xsf::log_expit(x) }
if x < 0.0 {
x - x.exp().ln_1p()
} else {
-(-x).exp().ln_1p()
}
}

/// Compute `log(1 - exp(x))`
/// Compute $\ln(1 - e^x)$
///
/// Translated into pure Rust from Cephes.
/// This function has no analogue in `scipy.special`.
///
/// # See also
/// - [`expm1`](crate::expm1)
#[must_use]
#[inline]
pub fn log1mexp(x: f64) -> f64 {
unsafe { crate::ffi::xsf::log1mexp(x) }
if x > 0.0 {
f64::NAN
} else if x == 0.0 {
f64::INFINITY
} else if x < -1.0 {
(-x.exp()).ln_1p()
} else {
(-x.exp_m1()).ln()
}
}

#[cfg(test)]
Expand Down
Loading