Skip to main content

LogLognormalKernelBundle

Struct LogLognormalKernelBundle 

Source
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: IntegratedExpectationMode

Implementations§

Source§

impl LogLognormalKernelBundle

Source

pub fn get(&self, k: usize) -> f64

Source

pub fn len(&self) -> usize

Source

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_k

expm1 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

Source§

fn clone(&self) -> LogLognormalKernelBundle

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for LogLognormalKernelBundle

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByRef<T> for T

Source§

fn by_ref(&self) -> &T

Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DistributionExt for T
where T: ?Sized,

Source§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V