1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! The log domain of probabilities and LLRs, without overflow: [`ln_1p_exp`],
//! [`max_star`] and its choice [`Jacobian`] (of `comnum-core`), [`log_sum_exp`] and [`log_sum_exp_iter`]
//! (re-exported at the root).
/// `ln(1 + e^x)` (the softplus) without overflow.
///
/// # Examples
/// ```
/// use comnum_math::ln_1p_exp;
/// assert!((ln_1p_exp(0.0) - 2f64.ln()).abs() < 1e-15);
/// assert_eq!(ln_1p_exp(1000.0), 1000.0);
/// ```
/// The Jacobian logarithm, exact or max-log: defined in `comnum-core`, since the soft
/// demapper trait [`comnum_core::traits::Demap`] takes it, and re-exported here for
/// [`max_star`], the BCJR and turbo decoders of `comnum-fec` and the demappers of
/// `comnum-mapping`.
pub use Jacobian;
/// The `max*` operation `ln(e^a + e^b)` of the log-MAP algorithms; `max(a, b)` with
/// [`Jacobian::MaxLog`] or when the maximum is not finite.
///
/// # Examples
/// ```
/// use comnum_math::{Jacobian, max_star};
/// assert!((max_star(0.0, 0.0, Jacobian::Exact) - 2f64.ln()).abs() < 1e-15);
/// assert_eq!(max_star(0.0, -1.0, Jacobian::MaxLog), 0.0);
/// ```
/// `ln Σ_i e^{v_i}` without overflow (the log domain of probabilities and LLRs).
///
/// # Examples
/// ```
/// use comnum_math::log_sum_exp;
/// assert!((log_sum_exp(&[1000.0, 1000.0]) - (1000.0 + 2f64.ln())).abs() < 1e-9);
/// assert_eq!(log_sum_exp(&[]), f64::NEG_INFINITY);
/// ```
/// [`log_sum_exp`] of the values of an iterator, traversed twice (no allocation).
///
/// # Examples
/// ```
/// use comnum_math::{log_sum_exp, log_sum_exp_iter};
/// let v = [0.5, -2.0, 3.0, 1.0];
/// // the terms of even index only
/// let even = log_sum_exp_iter(v.iter().step_by(2).copied());
/// assert_eq!(even, log_sum_exp(&[0.5, 3.0]));
/// ```