Skip to content

Commit 3044080

Browse files
committed
feat(core): fast math module
1 parent c99cf67 commit 3044080

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

crates/valib-core/src/math/fast.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
use crate::Scalar;
2+
use numeric_literals::replace_float_literals;
3+
use simba::simd::SimdBool;
4+
5+
/// Rational approximation of tanh(x) which is valid in the range -3..3
6+
///
7+
/// This approximation only includes the rational approximation part, and will diverge outside the
8+
/// bounds. In order to apply the tanh function over a bigger interval, consider clamping either the
9+
/// input or the output.
10+
///
11+
/// You should consider using [`tanh`] for a general-purpose faster tanh function, which uses
12+
/// branching.
13+
///
14+
/// Source: <https://www.musicdsp.org/en/latest/Other/238-rational-tanh-approximation.html>
15+
///
16+
/// # Arguments
17+
///
18+
/// * `x`: Input value (low-error range: -3..3)
19+
///
20+
/// returns: T
21+
#[replace_float_literals(T::from_f64(literal))]
22+
pub fn rational_tanh<T: Scalar>(x: T) -> T {
23+
x * (27. + x * x) / (27. + 9. * x * x)
24+
}
25+
26+
/// Fast approximation of tanh(x).
27+
///
28+
/// This approximation uses branching to clamp the output to -1..1 in order to be useful as a
29+
/// general-purpose approximation of tanh.
30+
///
31+
/// Source: <https://www.musicdsp.org/en/latest/Other/238-rational-tanh-approximation.html>
32+
///
33+
/// # Arguments
34+
///
35+
/// * `x`: Input value
36+
///
37+
/// returns: T
38+
pub fn tanh<T: Scalar>(x: T) -> T {
39+
rational_tanh(x).simd_clamp(-T::one(), T::one())
40+
}
41+
42+
/// Fast approximation of exp, with maximum error in -1..1 of 0.59%, and in -3.14..3.14 of 9.8%.
43+
///
44+
/// You should consider using [`exp`] for a better approximation which uses this function, but
45+
/// allows a greater range at the cost of branching.
46+
///
47+
/// Source: <https://www.musicdsp.org/en/latest/Other/222-fast-exp-approximations.html>
48+
///
49+
/// # Arguments
50+
///
51+
/// * `x`: Input value
52+
///
53+
/// returns: T
54+
#[replace_float_literals(T::from_f64(literal))]
55+
pub fn fast_exp5<T: Scalar>(x: T) -> T {
56+
(120. + x * (120. + x * (60. + x * (20. + x * (5. + x))))) * 0.0083333333
57+
}
58+
59+
/// Fast approximation of exp, using [`fast_exp5`]. Uses branching to get a bigger range.
60+
///
61+
/// Maximum error in the 0..10.58 range is 0.45%.
62+
///
63+
/// Source: <https://www.musicdsp.org/en/latest/Other/222-fast-exp-approximations.html>
64+
///
65+
/// # Arguments
66+
///
67+
/// * `x`:
68+
///
69+
/// returns: T
70+
#[replace_float_literals(T::from_f64(literal))]
71+
pub fn exp<T: Scalar>(x: T) -> T {
72+
x.simd_lt(2.5).if_else2(
73+
|| T::simd_e() * fast_exp5(x - 1.),
74+
(|| x.simd_lt(5.), || 33.115452 * fast_exp5(x - 3.5)),
75+
|| 403.42879 * fast_exp5(x - 6.),
76+
)
77+
}
78+
79+
/// Fast 2^x approximation, using [`exp`].
80+
///
81+
/// Maximum error in the 0..15.26 range is 0.45%.
82+
///
83+
/// Source: <https://www.musicdsp.org/en/latest/Other/222-fast-exp-approximations.html>
84+
///
85+
/// # Arguments
86+
///
87+
/// * `x`:
88+
///
89+
/// returns: T
90+
///
91+
/// # Examples
92+
///
93+
/// ```
94+
///
95+
/// ```
96+
pub fn pow2<T: Scalar>(x: T) -> T {
97+
let log_two = T::simd_ln_2();
98+
exp(log_two * x)
99+
}

crates/valib-core/src/math/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use simba::simd::{SimdBool, SimdComplexField};
88

99
use crate::Scalar;
1010

11+
pub mod fast;
1112
pub mod interpolation;
1213
pub mod lut;
1314
pub mod nr;
@@ -86,6 +87,7 @@ pub fn bilinear_prewarming_bounded<T: Scalar>(samplerate: T, wc: T) -> T {
8687
#[inline]
8788
pub fn smooth_min<T: Scalar>(t: T, a: T, b: T) -> T {
8889
let r = (-a / t).simd_exp2() + (-b / t).simd_exp2();
90+
// let r = fast::pow2(-a / t) + fast::pow2(-b / t);
8991
-t * r.simd_log2()
9092
}
9193

0 commit comments

Comments
 (0)