Skip to content

Commit

Permalink
Ver 0.37.8
Browse files Browse the repository at this point in the history
- Integrate with Lambert W crate (#63)
  • Loading branch information
Axect committed Jul 30, 2024
2 parents ffb9964 + 9247f21 commit 53fe74b
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 12 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "peroxide"
version = "0.37.7"
version = "0.37.8"
authors = ["axect <axect@outlook.kr>"]
edition = "2018"
description = "Rust comprehensive scientific computation library contains linear algebra, numerical analysis, statistics and machine learning tools with farmiliar syntax"
Expand Down Expand Up @@ -39,6 +39,7 @@ serde = { version = "1.0", features = ["derive"], optional = true }
json = { version = "0.12", optional = true }
arrow2 = { version = "0.18", features = ["io_parquet", "io_parquet_compression"], optional = true }
num-complex = { version = "0.4", optional = true }
lambert_w = { version = "0.3.0", default-features = false, features = ["24bits", "50bits"] }

[package.metadata.docs.rs]
rustdoc-args = [ "--html-in-header", "katex-header.html", "--cfg", "docsrs"]
Expand Down
23 changes: 23 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
# Release 0.37.8 (2024-07-30)

- Integrate with [lambert_w](https://crates.io/crates/lambert_w) crate ([#63](https://github.com/Axect/Peroxide/pull/63)) (Thanks to [@JSorngard](https://github.com/JSorngard))
- Write flexible wrapper for [lambert_w](https://crates.io/crates/lambert_w)
```rust
pub enum LambertWAccuracyMode {
Simple, // Faster, 24 bits of accuracy
Precise, // Slower, 50 bits of accuracy
}

pub fn lambert_w0(z: f64, mode: LambertWAccuracyMode) -> f64;
pub fn lambert_wm1(z: f64, mode: LambertWAccuracyMode) -> f64;
```

- Write default Lambert W function for `prelude` (Precise as default)
```rust
use peroxide::prelude::*;

fn main() {
lambert_w0(1.0).print(); // Same as fuga::lambert_w0(1.0, LambertWAccuracyMode::Simple)
}
```

# Release 0.37.7 (2024-07-05)

- Bump `pyo3` dependency to `0.22`
Expand Down
7 changes: 5 additions & 2 deletions src/prelude/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,10 @@ pub use crate::util::{api::*, low_level::*, non_macro::*, print::*, useful::*, w
pub use crate::statistics::{dist::*, ops::*, rand::*, stat::*};

#[allow(unused_imports)]
pub use crate::special::function::*;
pub use crate::special::function::{
beta, erf, erfc, gamma, gaussian, inc_beta, inc_gamma, inv_erf, inv_erfc, inv_inc_gamma,
inv_inc_beta, ln_gamma, phi, poch,
};

#[allow(unused_imports)]
pub use crate::numerical::{
Expand All @@ -206,7 +209,7 @@ pub use crate::numerical::{
utils::*,
};

pub use simpler::{eigen, integrate, chebyshev_polynomial, cubic_hermite_spline};
pub use simpler::{eigen, integrate, chebyshev_polynomial, cubic_hermite_spline, lambert_w0, lambert_w_m1};

#[allow(unused_imports)]
pub use crate::statistics::stat::Metric::*;
Expand Down
34 changes: 34 additions & 0 deletions src/prelude/simpler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,40 @@ pub fn cubic_hermite_spline(node_x: &[f64], node_y: &[f64]) -> anyhow::Result<Cu
spline::cubic_hermite_spline(node_x, node_y, Quadratic)
}

use crate::special::function::{
lambert_w0 as lambert_w0_flex, lambert_wm1 as lambert_w_m1_flex, LambertWAccuracyMode,
};

/// The principal branch of the Lambert W function, W_0(`z`).
///
/// Returns [`NAN`](f64::NAN) if the given input is smaller than -1/e (≈ -0.36787944117144233).
///
/// Accurate to 50 bits.
///
/// Wrapper of `lambert_w_0` function of `lambert_w` crate.
///
/// # Reference
///
/// [Toshio Fukushima, Precise and fast computation of Lambert W function by piecewise minimax rational function approximation with variable transformation](https://www.researchgate.net/publication/346309410_Precise_and_fast_computation_of_Lambert_W_function_by_piecewise_minimax_rational_function_approximation_with_variable_transformation)
pub fn lambert_w0(z: f64) -> f64 {
lambert_w0_flex(z, LambertWAccuracyMode::Precise)
}

/// The secondary branch of the Lambert W function, W_-1(`z`).
///
/// Returns [`NAN`](f64::NAN) if the given input is positive or smaller than -1/e (≈ -0.36787944117144233).
///
/// Accurate to 50 bits.
///
/// Wrapper of `lambert_w_m1` function of `lambert_w` crate.
///
/// # Reference
///
/// [Toshio Fukushima, Precise and fast computation of Lambert W function by piecewise minimax rational function approximation with variable transformation](https://www.researchgate.net/publication/346309410_Precise_and_fast_computation_of_Lambert_W_function_by_piecewise_minimax_rational_function_approximation_with_variable_transformation)
pub fn lambert_w_m1(z: f64) -> f64 {
lambert_w_m1_flex(z, LambertWAccuracyMode::Precise)
}

/// Simple handle parquet
#[cfg(feature="parquet")]
pub trait SimpleParquet: Sized {
Expand Down
58 changes: 49 additions & 9 deletions src/special/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub fn inc_beta(a: f64, b: f64, x: f64) -> f64 {
/// Inverse regularized incomplete beta function
///
/// Wrapper of `invbetai` function of `puruspe` crate
pub fn inv_inv_beta(p: f64, a: f64, b: f64) -> f64 {
pub fn inv_inc_beta(p: f64, a: f64, b: f64) -> f64 {
puruspe::invbetai(p, a, b)
}

Expand All @@ -118,11 +118,51 @@ pub fn phi(x: f64) -> f64 {
0.5 * (1f64 + erf(x / 2f64.sqrt()))
}

// /// Hypergeometric function 2F1
// ///
// /// Wrapper of `hyp2f1` function of `special-fun` crate
// pub fn hyp2f1(a: f64, b: f64, c: f64, x: f64) -> f64 {
// unsafe {
// special_fun::unsafe_cephes_double::hyp2f1(a, b, c, x)
// }
// }
/// The principal branch of the Lambert W function, W_0(`z`).
///
/// Returns [`NAN`](f64::NAN) if the given input is smaller than -1/e (≈ -0.36787944117144233).
///
/// Use [`Precise`](LambertWAccuracyMode::Precise) for 50 bits of accuracy and the [`Simple`](LambertWAccuracyMode::Simple) mode
/// for only 24 bits, but with faster execution time.
///
/// Wrapper of the `lambert_w_0` and `sp_lambert_w_0` functions of the `lambert_w` crate.
///
/// # Reference
///
/// [Toshio Fukushima, Precise and fast computation of Lambert W function by piecewise minimax rational function approximation with variable transformation](https://www.researchgate.net/publication/346309410_Precise_and_fast_computation_of_Lambert_W_function_by_piecewise_minimax_rational_function_approximation_with_variable_transformation)
pub fn lambert_w0(z: f64, mode: LambertWAccuracyMode) -> f64 {
match mode {
LambertWAccuracyMode::Precise => lambert_w::lambert_w_0(z),
LambertWAccuracyMode::Simple => lambert_w::sp_lambert_w_0(z),
}
.unwrap_or(f64::NAN)
}

/// The secondary branch of the Lambert W function, W_-1(`z`).
///
/// Returns [`NAN`](f64::NAN) if the given input is positive or smaller than -1/e (≈ -0.36787944117144233).
///
/// Use [`Precise`](LambertWAccuracyMode::Precise) for 50 bits of accuracy and the [`Simple`](LambertWAccuracyMode::Simple) mode
/// for only 24 bits, but with faster execution time.
///
/// Wrapper of the `lambert_w_m1` and `sp_lambert_w_m1` functions of the `lambert_w` crate.
///
/// # Reference
///
/// [Toshio Fukushima, Precise and fast computation of Lambert W function by piecewise minimax rational function approximation with variable transformation](https://www.researchgate.net/publication/346309410_Precise_and_fast_computation_of_Lambert_W_function_by_piecewise_minimax_rational_function_approximation_with_variable_transformation)
pub fn lambert_wm1(z: f64, mode: LambertWAccuracyMode) -> f64 {
match mode {
LambertWAccuracyMode::Precise => lambert_w::lambert_w_m1(z),
LambertWAccuracyMode::Simple => lambert_w::sp_lambert_w_m1(z),
}
.unwrap_or(f64::NAN)
}

/// Decides the accuracy mode of the Lambert W functions.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LambertWAccuracyMode {
/// Faster, 24 bits of accuracy.
Simple,
/// Slower, 50 bits of accuracy.
Precise,
}
7 changes: 7 additions & 0 deletions tests/special.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use peroxide::fuga::{*, LambertWAccuracyMode::*};

#[test]
fn lambert_w_test() {
assert_eq!(lambert_w0(1.0, Precise), 0.567143290409784);
assert!(nearly_eq(lambert_w0(1.0, Simple), 0.567143290409784));
}

0 comments on commit 53fe74b

Please sign in to comment.