pub struct LogLognormalKernelBundle {
pub log_values: Vec<f64>,
pub log_laplace: Vec<f64>,
pub log_scaled_a_derivatives: Option<Vec<KernelSignedLog>>,
pub mode: IntegratedExpectationMode,
}Expand description
Kernel bundle storing log K_{k,m} values instead of K_{k,m}.
Fields§
§log_values: Vec<f64>§log_laplace: Vec<f64>The Laplace half of each log_values entry, kept apart from the
analytic prefix (#2610).
log K_k = prefix_k + laplace_k with prefix_k = k·μ + σ²k²/2 known in
closed form. Storing the two halves summed is enough to READ a kernel
value but not enough to difference one accurately, because the prefix
grows quadratically in k and swamps the Laplace part it is added to.
Retaining laplace_k costs one f64 per rung and is what lets
Self::second_cumulant_ratio recover the exact part of a second
difference instead of subtracting it away.
log_scaled_a_derivatives: Option<Vec<KernelSignedLog>>σ^j · ∂_a^j K_0 in signed-log coordinates for j = 0..=max_k, where
a = μ + ln m is the SINGLE location the k = 0 kernel depends on
(#2610), or None when the analytic branch does not apply.
K_0(m,μ,σ) = S(μ + ln m, σ) because m and μ enter only through the
product m·e^U. That makes ∂_a the one derivative the rung ladder is
built out of:
m^k K_k = (−1)^k · ∂_a(∂_a − 1)···(∂_a − k + 1) K_0,so a term list in the K_k basis and one in the ∂_a^j K_0 basis carry
the SAME information — but not the same conditioning. Reaching
∂_a^4 K_0 through the rungs means evaluating −mK_1 + 7m²K_2 − 6m³K_3 + m⁴K_4, whose summands are O(1/σ) while the sum is O(1/σ^5); reading
it from here is one quadrature over an integrand that is already small.
The scaling by σ^j is what keeps every entry inside the representable
range: ∂_a^4 K_0 itself is ~1e-17 at log σ = 7.
Entry j = 0 is log_values[0] verbatim, so a term list that only
reaches k = 0 evaluates bit-identically on either basis.
mode: IntegratedExpectationModeImplementations§
Source§impl LogLognormalKernelBundle
impl LogLognormalKernelBundle
pub fn get(&self, k: usize) -> f64
pub fn len(&self) -> usize
Sourcepub fn second_cumulant_ratio(&self, k: usize, sigma: f64) -> Option<f64>
pub fn second_cumulant_ratio(&self, k: usize, sigma: f64) -> Option<f64>
K_{k+2}/K_k − (K_{k+1}/K_k)², formed without the cancelling
subtraction (#2610).
The naive route evaluates both ratios and subtracts. In the large-σ
regime they agree to ~1/(120σ²) of their own size, so the difference
keeps only the bits they do NOT share and the result is noise past
log σ ≈ 5.4 — no working precision repairs that, because the cancelled
quantity keeps shrinking while the roundoff floor does not (#2566).
Factoring the common ratio out first turns the subtraction into one
expm1:
R₂ − R₁² = R₂ · (1 − e^Δ) = −R₂ · expm1(Δ), Δ = 2L_{k+1} − L_{k+2} − L_kexpm1 is exact to full relative precision as Δ → 0, which is
precisely where the difference form fails. That alone would only move
the problem into Δ, a second difference of large log-values — except
that the prefix’s second difference is available in closed form:
prefix_{k+2} − 2·prefix_{k+1} + prefix_k = σ² exactly, for every k and μSo Δ = −(σ² + D²laplace): the dominant term is exact, and only the
slowly-varying Laplace half is differenced numerically. For m = 0 the
Laplace half is identically zero and Δ = −σ² is exact outright.
Returns None when the rung is missing or any input is non-finite —
a caller that cannot form this must fall back rather than receive a
silently degraded number.
Trait Implementations§
Source§impl Clone for LogLognormalKernelBundle
impl Clone for LogLognormalKernelBundle
Source§fn clone(&self) -> LogLognormalKernelBundle
fn clone(&self) -> LogLognormalKernelBundle
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for LogLognormalKernelBundle
impl RefUnwindSafe for LogLognormalKernelBundle
impl Send for LogLognormalKernelBundle
impl Sync for LogLognormalKernelBundle
impl Unpin for LogLognormalKernelBundle
impl UnsafeUnpin for LogLognormalKernelBundle
impl UnwindSafe for LogLognormalKernelBundle
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.