Skip to main content

DoubleT

Struct DoubleT 

struct DoubleT {
    factor: UnitStudentT,
    idiosyncratic: UnitStudentT,
}
Expand description

The double-t copula’s two unit-variance t distributions.

Fields§

§factor: UnitStudentT§idiosyncratic: UnitStudentT

Implementations§

§

impl DoubleT

fn new(factor_dof: f64, idiosyncratic_dof: f64) -> Self

fn breakpoints( thresholds: &[f64], sqrt_rho: f64, denom: f64, reach: f64, ) -> Vec<f64>

The factor line’s breakpoints, passive and sorted: the factor’s bulk and each threshold’s transition window, each cut at centre ± {1, 2, 4, 6}·scale, and a geometric ladder ±6·4ᵏ out to reach and past every window.

A t factor’s tails are too heavy for the Gaussian’s truncation at ±8, and a small correlation puts a name’s transition far out in them (C/√ρ ≈ −40 for a 1bp default probability at 5%) — so the grid follows the thresholds. The cuts are set by where the integrand stops being analytic: the unit t density has poles at ±i·√(ν − 2), the conditional probability at √(ν̄ − 2)·w off the real axis about its centre C/√ρ, w = √(1−ρ)/√ρ. Gauss–Legendre on one panel across [−6, 6] converges only as fast as that pole’s distance allows (it lost 2e-8 of a t₃’s mass); on panels no wider than the distance it is exact to rounding. Past the windows the integrand is a product of power-law tails, resolved on panels whose ends are within a factor of four.

fn grid(&self, points: &[f64]) -> Vec<(f64, f64)>

The factor grid over the panels the breakpoints cut, (m, dm·f_M(m)) pairs: Σ wᵢ·g(mᵢ) ≈ E[g(M)].

fn lifts<R: Scalar>(&self, marks: Option<(R, R)>) -> Option<NuLifts>

The ν-lifts marks needs, if any.

fn conditional_marked<R: Scalar>( &self, threshold: R, sqrt_rho: R, denom: R, m: R, marks: Option<(R, R)>, lifts: Option<NuLifts>, ) -> R

The name’s conditional default probability at factor m, the idiosyncratic ν lifted by marks.

fn latent<R: Scalar>( &self, grid: &[(f64, f64)], x: R, sqrt_rho: R, denom: R, ) -> (R, R)

The latent variable’s CDF H(x) and density h(x) over a grid.

fn latent_marked<R: Scalar>( &self, grid: &[(f64, f64)], x: R, sqrt_rho: R, denom: R, (df, di): (R, R), lifts: NuLifts, ) -> (R, R)

latent with both degrees of freedom lifted: the idiosyncratic CDF and density in ν, and each factor weight w corrected by w·(g_ν·Δν + ½(g_νν + g_ν²)·Δν²). The corrections are summed apart and are zero-valued, so the value is the unmarked sum’s.

fn threshold<R: Scalar>( &self, pd: R, sqrt_rho: R, denom: R, marks: Option<(R, R)>, ) -> (R, Vec<(f64, f64)>)

The default threshold C = H⁻¹(pd) and the grid it was solved on.

Newton from Φ⁻¹(pd) (X has unit variance), safeguarded by a bracket, passively to rounding, the grid following the iterate’s transition window; then two Newton steps in the mode on the final grid. The passive residual is at rounding level, so the value does not move, and each step doubles the orders of the implicit derivatives ∂C/∂pd, ∂C/∂ρ it carries — two give three.

fn capped_loss<R: Scalar>( &self, pd: R, lgd: R, cap: f64, rho: R, marks: Option<(R, R)>, ) -> R

The double-t LHP expected capped loss E[min(L, K)], as the Gaussian’s capped_loss: K below the kink m* = (C − √(1−ρ)·F_Z⁻¹(K/lgd))/√ρ, in closed form K·F_M(m*), and the smooth piece above it on the panels past the kink, the first starting at the kink so its nodes move with it in the mode. A cap at or above lgd is never reached: the loss is lgd·pd, exactly the marginal the threshold was solved to.

Auto Trait Implementations§

Blanket Implementations§

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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.