pub struct PrecomputedTransmissionModel {
pub cross_sections: Arc<Vec<Vec<f64>>>,
pub density_indices: Arc<Vec<usize>>,
pub instrument: Option<Arc<InstrumentParams>>,
pub resolution_plan: Option<Arc<ResolutionPlan>>,
pub sparse_cubature_plan: Option<Arc<SparseEmpiricalCubaturePlan>>,
pub sparse_scalar_plan: Option<Arc<ScalarSurrogatePlan>>,
pub layout: Arc<WorkingGridLayout>,
}Expand description
Transmission model backed by precomputed Doppler-broadened cross-sections.
The expensive physics steps (resonance → σ(E), Doppler broadening) are
computed once and stored. Each evaluate() call performs Beer-Lambert
and, when instrument is present, resolution broadening on the total
transmission:
T(E) = R ⊗ exp(−Σᵢ nᵢ · σ_{D,i}(E))
Issue #442: resolution broadening is applied to T(E) after Beer-Lambert, not to σ(E) before.
Fields§
§cross_sections: Arc<Vec<Vec<f64>>>§density_indices: Arc<Vec<usize>>Mapping: params[density_indices[i]] is the density of isotope i.
Wrapped in Arc so that parallel pixel loops can share one copy
via cheap reference-count increments instead of deep-cloning per pixel.
instrument: Option<Arc<InstrumentParams>>Instrument resolution parameters.
When Some, resolution broadening is applied to the total
transmission after Beer-Lambert in evaluate().
resolution_plan: Option<Arc<ResolutionPlan>>§sparse_cubature_plan: Option<Arc<SparseEmpiricalCubaturePlan>>Optional sparse empirical cubature plan.
When the plan is present AND its target_energies match this
model’s energy grid AND cubature.k() == n_density_params
AND no temperature / energy-scale fitting is active, the
evaluate() / analytical_jacobian() fast path calls
cubature.forward_and_jacobian(n) directly instead of
exp(-Σ n σ) + apply_resolution. Any guard failure falls
back to the exact path, so installing a plan cannot change
results unless every guard passes.
sparse_scalar_plan: Option<Arc<ScalarSurrogatePlan>>Optional scalar (k = 1) surrogate plan.
Mutually exclusive with sparse_cubature_plan in practice —
the cubature dispatch fires only for k ≥ 2 and the scalar
plan only for k == 1. The type alias
ScalarSurrogatePlan = ScalarChebyshevPlan is kept as a
stable public name so a future scalar surrogate can swap in
without touching this field or any dispatch call site.
Chebyshev-in-density was picked over Lanczos Gauss
quadrature after a real-VENUS bench-off (Chebyshev won on
both the accuracy and wall-time axes; see
nereids_physics::surrogate module docs).
layout: Arc<WorkingGridLayout>Trait Implementations§
Source§impl FitModel for PrecomputedTransmissionModel
impl FitModel for PrecomputedTransmissionModel
Source§fn analytical_jacobian(
&self,
params: &[f64],
free_param_indices: &[usize],
y_current: &[f64],
) -> Option<FlatMatrix>
fn analytical_jacobian( &self, params: &[f64], free_param_indices: &[usize], y_current: &[f64], ) -> Option<FlatMatrix>
Analytical Jacobian for the Beer-Lambert transmission model.
Without resolution: T(E) = exp(-Σᵢ nᵢ · σᵢ(E)) ∂T/∂nᵢ = -σᵢ(E) · T(E)
With resolution (R is a linear operator): T_obs(E) = R[T](E) = R[exp(-Σᵢ nᵢ · σᵢ)](E) ∂T_obs/∂nᵢ = R[-σᵢ(E) · T(E)]
For grouped isotopes sharing density parameter N_g: ∂T_obs/∂N_g = R[-(Σ_{i∈g} σᵢ(E)) · T(E)]
Source§impl ForwardModel for PrecomputedTransmissionModel
impl ForwardModel for PrecomputedTransmissionModel
Source§fn predict(&self, params: &[f64]) -> Result<Vec<f64>, FittingError>
fn predict(&self, params: &[f64]) -> Result<Vec<f64>, FittingError>
Auto Trait Implementations§
impl Freeze for PrecomputedTransmissionModel
impl RefUnwindSafe for PrecomputedTransmissionModel
impl Send for PrecomputedTransmissionModel
impl Sync for PrecomputedTransmissionModel
impl Unpin for PrecomputedTransmissionModel
impl UnsafeUnpin for PrecomputedTransmissionModel
impl UnwindSafe for PrecomputedTransmissionModel
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<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
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 more