pub struct Dual2<S: JetField> {
pub v: S,
pub g: S,
pub h: S,
}Expand description
A single-direction second-order jet over the field S: value v, first
derivative g, second derivative h, all with respect to ONE seeded
direction. Nest it (Dual2<Dual2<f64>>) for a second, independent direction.
Fields§
§v: SValue channel.
g: SFirst derivative in this dual’s direction.
h: SSecond derivative in this dual’s direction.
Implementations§
Source§impl<S: JetFieldConst> Dual2<S>
impl<S: JetFieldConst> Dual2<S>
Source§impl Dual2<Dual2<f64>>
impl Dual2<Dual2<f64>>
Sourcepub fn seed_outer(x: f64) -> Self
pub fn seed_outer(x: f64) -> Self
Seed a primary that varies only along the OUTER direction a
(∂/∂a = 1, ∂/∂b = 0) — the Tower4::variable(x, 0) analogue.
Sourcepub fn seed_inner(x: f64) -> Self
pub fn seed_inner(x: f64) -> Self
Seed a primary that varies only along the INNER direction b
(∂/∂a = 0, ∂/∂b = 1) — the Tower4::variable(x, 1) analogue.
Sourcepub fn seed_directional(base: f64, d1: f64, d2: f64) -> Self
pub fn seed_directional(base: f64, d1: f64, d2: f64) -> Self
Seed a primary at value base that moves as base + s·d1 + t·d2 under the
two independent scalar directions s (outer a) and t (inner b):
∂/∂a = d1, ∂/∂b = d2, all second-and-higher self-derivatives zero
(the primary is affine in s, t). This is what a directional
bidirectional contraction along arbitrary weight vectors d1, d2 needs —
seed every primary i with seed_directional(base_i, d1_i, d2_i), run
the program, and read channels()[8] (∂²_a ∂²_b) for
Σ_{a,b,c,d} ℓ_{abcd}·d1_a d1_b d2_c d2_d.
Sourcepub fn from_channels(c: [f64; 9]) -> Self
pub fn from_channels(c: [f64; 9]) -> Self
Build a nested dual directly from its nine (s-order, t-order) channels,
ordered as Self::channels: [v, ∂a, ∂b, ∂aa, ∂ab, ∂bb, ∂aab, ∂abb, ∂aabb]. The inverse of Self::channels. Used to assemble the result of
a channel-space operation (e.g. a moment-recurrence residual term) back
into a Dual22.
Sourcepub fn channels(&self) -> [f64; 9]
pub fn channels(&self) -> [f64; 9]
The nine channels this nested dual represents, keyed to the two-primary
crate::jet_tower::Tower4 indices 0 (outer a) and 1 (inner b):
(value, ∂a, ∂b, ∂aa, ∂ab, ∂bb, ∂aab, ∂abb, ∂aabb).
Trait Implementations§
impl<S: Copy + JetField> Copy for Dual2<S>
Source§impl<S: JetField> JetField for Dual2<S>
impl<S: JetField> JetField for Dual2<S>
fn add(&self, o: &Self) -> Self
fn sub(&self, o: &Self) -> Self
fn mul(&self, o: &Self) -> Self
fn neg(&self) -> Self
Source§fn compose_unary(&self, d: [f64; 5]) -> Self
fn compose_unary(&self, d: [f64; 5]) -> Self
f ∘ self given the OUTER real function’s
derivative stack d = [f(u), f′(u), f″(u), f‴(u), f⁗(u)] evaluated at
u = self.value() — the identical [f64; 5] stack shape
crate::jet_tower::Tower4::compose_unary consumes.Source§impl<S: JetFieldConst> JetFieldConst for Dual2<S>
impl<S: JetFieldConst> JetFieldConst for Dual2<S>
Source§impl<S, const K: usize> JetScalar<K> for Dual2<S>where
S: JetScalar<K>,
Lift a fixed-width primary jet through an independent second-order
direction. Primary variables live in the inner scalar; constructing one
must not seed the outer direction, which is reserved for a family or
hyperparameter derivative selected by the caller.
impl<S, const K: usize> JetScalar<K> for Dual2<S>where
S: JetScalar<K>,
Lift a fixed-width primary jet through an independent second-order direction. Primary variables live in the inner scalar; constructing one must not seed the outer direction, which is reserved for a family or hyperparameter derivative selected by the caller.
Source§fn variable(x: f64, axis: usize) -> Self
fn variable(x: f64, axis: usize) -> Self
p_axis at value x: unit first derivative in slot
axis, all higher channels zero. (The nilpotent / cross channels of the
directional scalars are seeded zero — callers set ε/δ directions through
the scalar-specific OneSeed::seed_direction / TwoSeed::seed.)Source§fn symmetric_quadratic_form<C: SymmetricQuadraticCoefficients>(
inputs: &[Self],
coefficients: &C,
) -> Self
fn symmetric_quadratic_form<C: SymmetricQuadraticCoefficients>( inputs: &[Self], coefficients: &C, ) -> Self
inputs' A inputs from one universal semantic primitive.
Order-specific scalars may lower the mechanically derived channels
directly; the default is the exact scalar program over mul/add/scale.Source§fn linear_combination(inputs: &[Self], weights: &[f64]) -> Self
fn linear_combination(inputs: &[Self], weights: &[f64]) -> Self
sum_i weights[i] * inputs[i] in one semantic primitive.Source§fn add_constant(&self, constant: f64) -> Self
fn add_constant(&self, constant: f64) -> Self
Source§fn multiply_add(&self, right: &Self, addend: &Self) -> Self
fn multiply_add(&self, right: &Self, addend: &Self) -> Self
self * right + addend in one semantic primitive.Source§fn composed_sum(inputs: &[Self], derivative_stacks: &[[f64; 5]]) -> Self
fn composed_sum(inputs: &[Self], derivative_stacks: &[[f64; 5]]) -> Self
Source§fn affine_compose(
&self,
input_scale: f64,
input_shift: f64,
derivative_stack: [f64; 5],
) -> Self
fn affine_compose( &self, input_scale: f64, input_shift: f64, derivative_stack: [f64; 5], ) -> Self
u = input_scale * self + input_shift.Source§fn affine_composed_sum(
inputs: &[Self],
input_scales: &[f64],
derivative_stacks: &[[f64; 5]],
) -> Self
fn affine_composed_sum( inputs: &[Self], input_scales: &[f64], derivative_stacks: &[[f64; 5]], ) -> Self
Σ_i f_i(input_scale_i · (left_i · right + addend_scale_i · addend))
from the certified derivative stack of each f_i. The shared operands
make expression-level common subexpressions explicit, so optimized
backends apply their inherited derivative channels once. Expression
arity is part of the type, and borrowed operands never copy a full tower.
An exact-zero addend scale (either sign of IEEE zero) removes that addend
from the corresponding term entirely.Source§fn compose_unary_with(&self, stack_fn: impl Fn(f64) -> [f64; 5]) -> Self
fn compose_unary_with(&self, stack_fn: impl Fn(f64) -> [f64; 5]) -> Self
stack_fn. This evaluates
stack_fn(self.value()) once and forwards to
compose_unary, so it is bit-identical to the
explicit self.compose_unary(stack_fn(self.value())) form.Source§fn ln(&self) -> Self
fn ln(&self) -> Self
ln(self). Caller guarantees positivity. Same derivative stack
crate::jet_tower::Tower4::ln uses, so any program written over both
matches term-for-term.Source§fn powf(&self, a: f64) -> Self
fn powf(&self, a: f64) -> Self
self^a for real exponent a. Caller guarantees a positive base.
Mirrors crate::jet_tower::Tower4::powf (falling-factorial stack).Source§fn ln_gamma(&self) -> Self
fn ln_gamma(&self) -> Self
ln Γ(self). Caller guarantees a positive argument. Uses the SAME
hand-certified derivative stack crate::jet_tower::Tower4::ln_gamma
consumes (crate::jet_tower::ln_gamma_derivative_stack), so any
program written over both matches term-for-term.Source§fn digamma(&self) -> Self
fn digamma(&self) -> Self
ψ(self) = d/dx ln Γ(x) (digamma). Caller guarantees a positive
argument. Same hand-certified stack
crate::jet_tower::digamma_derivative_stack.Auto Trait Implementations§
impl<S> Freeze for Dual2<S>where
S: Freeze,
impl<S> RefUnwindSafe for Dual2<S>where
S: RefUnwindSafe,
impl<S> Send for Dual2<S>where
S: Send,
impl<S> Sync for Dual2<S>where
S: Sync,
impl<S> Unpin for Dual2<S>where
S: Unpin,
impl<S> UnsafeUnpin for Dual2<S>where
S: UnsafeUnpin,
impl<S> UnwindSafe for Dual2<S>where
S: UnwindSafe,
Blanket Implementations§
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,
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.