Skip to main content

gam_models/
transformation_normal.rs

1//! Conditional transformation model: estimate h(y|x) such that h(Y|x) ~ N(0,1).
2//!
3//! Given a response variable y and covariates x with a pre-built covariate design
4//! operator, this family estimates a smooth monotone transformation h(y | x) mapping
5//! the conditional distribution of Y|x onto a standard normal.
6//!
7//! The response-direction basis is `[1, I_1(y), ..., I_K(y)]`, tensored with an
8//! arbitrary covariate design operator. Column 0 is an unconstrained location
9//! component `b(x)`. The I-spline columns are shape components with squared
10//! covariate-side coefficients, giving the SCOP representation
11//! `h(y, x) = b(x) + ε·(y−median_y) + Σ_k I_k(y) γ_k(x)^2` and
12//! `h'(y, x) = ε + Σ_k M_k(y) γ_k(x)^2`. Monotonicity is structural:
13//! the fixed derivative floor `ε` keeps the change-of-variables log-density
14//! away from the `log(0)` singularity, while the non-negative M-spline basis
15//! and squared covariate-side coefficients supply the learned shape.
16//!
17//! The log-likelihood per observation is the finite-support normalized
18//! change-of-variables density for a standard normal target:
19//!
20//!   ℓ_i = -½ h_i² + log(h'_i) - log(Φ(h_U(x_i)) - Φ(h_L(x_i)))
21//!
22//! where `h_i = b(x_i) + ε·(y_i−median_y) + Σ_k I_k(y_i) γ_k(x_i)^2`
23//! and `h'_i = ε + Σ_k M_k(y_i) γ_k(x_i)^2`. The endpoint normalizer is
24//! required because the I-spline response basis saturates at finite support
25//! values rather than mapping onto the full real line.
26
27mod endpoint_normalizer;
28
29// Shared imports re-exported so every concern submodule pulls them through
30// `use super::*;` without re-listing. `pub(crate)` lets the child globs see them.
31pub(crate) use endpoint_normalizer::{
32    LogNormalCdfDiffDerivatives, endpoint_chain_first, endpoint_chain_fourth,
33    endpoint_chain_second, endpoint_chain_third, log_normal_cdf_diff,
34    log_normal_cdf_diff_derivatives,
35};
36
37pub(crate) use gam_terms::basis::{
38    BasisOptions, Dense, KnotSource, create_basis, create_difference_penalty_matrix,
39    create_ispline_derivative_dense,
40};
41pub(crate) use gam_linalg::faer_ndarray::{fast_ab, fast_abt, fast_atb};
42pub(crate) use crate::custom_family::{
43    BlockWorkingSet, BlockwiseFitOptions, CustomFamily, CustomFamilyBlockPsiDerivative,
44    CustomFamilyPsiDerivativeOperator, CustomFamilyWarmStart, ExactNewtonJointGradientEvaluation,
45    ExactNewtonJointHessianWorkspace, ExactNewtonJointPsiSecondOrderTerms,
46    ExactNewtonJointPsiTerms, ExactNewtonJointPsiWorkspace, FamilyEvaluation,
47    JointHessianSourcePreference, MaterializablePsiDerivativeOperator, MaterializationIntent,
48    ParameterBlockSpec, ParameterBlockState, PenaltyMatrix, evaluate_custom_family_joint_hyper,
49    evaluate_custom_family_joint_hyper_efs, fit_custom_family, fit_custom_family_fixed_log_lambdas,
50};
51pub(crate) use crate::penalized_projection::solve_penalizedweighted_projection;
52pub(crate) use crate::spatial_psi_bridge::build_block_spatial_psi_derivatives;
53pub(crate) use gam_terms::basis::initializewiggle_knots_from_seed;
54pub(crate) use crate::inference::model::{
55    TRANSFORMATION_SCORE_PIT_CLIP_EPS, TransformationScoreCalibration,
56};
57pub(crate) use gam_linalg::matrix::{
58    DenseDesignMatrix, DenseDesignOperator, DesignMatrix, LinearOperator, SymmetricMatrix,
59    dense_rowwise_kronecker,
60};
61pub(crate) use crate::model_types::UnifiedFitResult;
62pub(crate) use gam_solve::pirls::LinearInequalityConstraints;
63pub(crate) use crate::probability::standard_normal_quantile;
64pub(crate) use gam_terms::smooth::{
65    SpatialLengthScaleOptimizationOptions, SpatialLogKappaCoords, TermCollectionDesign,
66    TermCollectionSpec,
67};
68pub(crate) use crate::fit_orchestration::drivers::{
69    ExactJointHyperSetup, freeze_term_collection_from_design,
70    optimize_spatial_length_scale_exact_joint, spatial_length_scale_term_indices,
71};
72// #1521: relocated DOWN into gam_terms::smooth (was drivers::build_term_collection_design).
73pub(crate) use gam_terms::smooth::build_term_collection_design;
74pub(crate) use gam_problem::{
75    DriftDerivResult, HyperOperator, ProjectedFactorCache, ProjectedFactorKey,
76};
77pub(crate) use gam_runtime::resource::{MatrixMaterializationError, ResourcePolicy};
78pub(crate) use ndarray::{Array1, Array2, ArrayView1, ArrayView2, ArrayViewMut2, s};
79pub(crate) use std::cell::RefCell;
80pub(crate) use std::sync::{Arc, Mutex, OnceLock};
81
82mod config;
83mod custom_family;
84mod error;
85mod family;
86mod fit;
87mod kronecker_design;
88mod operators;
89mod penalty_scaling;
90mod psi_operator;
91mod response_basis;
92mod scop_curvature;
93mod scop_density;
94mod scop_psi;
95mod warm_start;
96
97pub use config::*;
98pub use error::*;
99pub use family::*;
100pub use fit::*;
101pub(crate) use kronecker_design::*;
102pub(crate) use operators::*;
103pub(crate) use penalty_scaling::*;
104pub use psi_operator::*;
105pub use response_basis::effective_response_num_internal_knots;
106pub(crate) use response_basis::{
107    assert_rowwise_kronecker_dimensions, build_response_basis, response_endpoint_value_bases,
108    response_floor_offsets,
109};
110pub use scop_density::*;
111pub(crate) use warm_start::*;
112
113#[cfg(test)]
114mod tests;