pub struct FitConfig {Show 51 fields
pub family: Option<String>,
pub negative_binomial_theta: Option<f64>,
pub link: Option<String>,
pub flexible_link: bool,
pub offset_column: Option<String>,
pub noise_offset_column: Option<String>,
pub frailty: FrailtySpec,
pub baseline_target: String,
pub baseline_scale: Option<f64>,
pub baseline_shape: Option<f64>,
pub baseline_rate: Option<f64>,
pub baseline_makeham: Option<f64>,
pub time_basis: String,
pub time_degree: usize,
pub time_num_internal_knots: usize,
pub time_smooth_lambda: f64,
pub survival_likelihood: Option<String>,
pub survival_time_anchor: Option<f64>,
pub survival_distribution: String,
pub threshold_time_k: Option<usize>,
pub threshold_time_degree: usize,
pub sigma_time_k: Option<usize>,
pub sigma_time_degree: usize,
pub logslope_time_k: Option<usize>,
pub logslope_time_degree: usize,
pub noise_formula: Option<String>,
pub logslope_formula: Option<String>,
pub z_column: Option<String>,
pub weight_column: Option<String>,
pub expectile_tau: Option<f64>,
pub ctn_stage1: Option<CtnStage1Recipe>,
pub scale_dimensions: bool,
pub spatial_optimization: SpatialLengthScaleOptimizationOptions,
pub adaptive_regularization: Option<bool>,
pub ridge_lambda: f64,
pub transformation_normal: bool,
pub firth: bool,
pub outer_max_iter: Option<usize>,
pub gpu_policy: GpuPolicy,
pub resource_policy: Option<ResourcePolicy>,
pub group_metadata: Option<BTreeMap<String, Value>>,
pub training_table_kind: String,
pub coefficient_groups: Vec<CoefficientGroupSpec>,
pub penalty_block_gamma_priors: Vec<(String, f64, f64)>,
pub latents: Option<Value>,
pub analytic_penalties: Option<Value>,
pub smooth_overrides: Option<Value>,
pub persistent_warm_start_store: Option<ConfiguredWarmStartStore>,
pub spatial_center_counts: Option<Vec<Option<usize>>>,
pub precompute_conformal: Option<bool>,
pub compute_covariance: Option<bool>,
}Fields§
§family: Option<String>Family: “gaussian”, “binomial”, “poisson”, “negative-binomial”, “gamma”, “tweedie” (alias “tw”; variance power fixed at p = 1.5), or None for auto-detect.
negative_binomial_theta: Option<f64>Fixed size/overdispersion parameter for family="negative-binomial".
link: Option<String>Link: “identity”, “logit”, “probit”, “cloglog”, “sas”, “beta-logistic”, or None.
flexible_link: boolWhether to use flexible (wiggle-augmented) link.
offset_column: Option<String>Optional additive offset column for the primary linear predictor.
noise_offset_column: Option<String>Optional additive offset column for the noise/log-scale predictor.
frailty: FrailtySpecFamily-level frailty. None is represented only by
FrailtySpec::None; an outer Option would create two null states.
baseline_target: StringBaseline target: “linear”, “weibull”, “gompertz”, “gompertz-makeham”.
baseline_scale: Option<f64>§baseline_shape: Option<f64>§baseline_rate: Option<f64>§baseline_makeham: Option<f64>§time_basis: StringTime basis: “ispline” or “none”.
time_degree: usize§time_num_internal_knots: usize§time_smooth_lambda: f64§survival_likelihood: Option<String>Survival likelihood mode: Some("transformation" | "location-scale" | "weibull" | "marginal-slope" | "latent" | "latent-binary"), or None
(the default), which resolves to "transformation" at the Surv(...)
materialization seam via FitConfig::resolved_survival_likelihood
(#2301 — no library-side string default). Some(_) on a non-survival
response is a typed configuration error.
survival_time_anchor: Option<f64>Explicit centering anchor for the baseline time basis, in the data’s own
time units. None (the default) lets
resolve_survival_time_anchor_for_mode pick it from the likelihood mode
and the truncation shape of the data: the robust interior median exit for
marginal-slope and for any genuinely left-truncated dataset (#751/#1790),
the earliest entry age otherwise.
This is model configuration, not front-end transport (#2631). It used to
exist only as the CLI’s --survival-time-anchor, which meant the flag was
silently dropped on the CLI’s own default (transformation / Weibull)
route — that route delegates to fit_from_formula, which had nowhere to
receive it — and a gam.fit-request document could not express the anchor
even though the flag declares a conflict with --request.
survival_distribution: StringResidual distribution: “gaussian”, “logistic”, “gumbel”.
threshold_time_k: Option<usize>§threshold_time_degree: usize§sigma_time_k: Option<usize>§sigma_time_degree: usize§logslope_time_k: Option<usize>Number of B-spline basis functions on the log t margin of the
log-slope block for the survival marginal-slope family (gam#2765,
gam#2767). None — the default — is a slope that does not move along
follow-up. Any Some(k) makes b a fitted surface in (x, t): the
log-slope covariate design is tensored against the time margin and the
row program carries b at the row’s entry time, at its exit time, and
the exit-time rate, so the event density picks up the q₁·c′₁ + ḃᵀz
terms a constant slope zeroes out.
logslope_time_degree: usizePolynomial degree of that margin. Shares the default (3) and the
k >= degree + 1 admission rule with the threshold and sigma margins.
noise_formula: Option<String>If set, fit a location-scale model with this formula for the noise parameter.
logslope_formula: Option<String>Formula for the log-slope model (survival marginal-slope or Bernoulli marginal-slope).
z_column: Option<String>Column name for the z (exposure/dose) variable in marginal-slope models.
weight_column: Option<String>Optional non-negative per-row training weights column.
expectile_tau: Option<f64>Expectile asymmetry τ ∈ (0, 1) for family = "expectile".
When family resolves to "expectile" the fit minimizes the
Newey–Powell asymmetric squared loss Σ wᵢ(τ)·(yᵢ − μᵢ)² with
wᵢ(τ) = τ if yᵢ > μᵢ else 1 − τ, tracing the conditional
τ-expectile — the smooth analogue of the τ-quantile. τ = 0.5
reduces exactly to the Gaussian-identity mean fit. The whole penalized
smooth + REML λ-selection machinery is reused via a Least
Asymmetrically Weighted Squares (LAWS) outer loop. None defaults to
the median expectile τ = 0.5 when the family is "expectile"; it is
ignored for every other family. The asymmetry may also be written inline
as family = "expectile(0.9)", which fills this field at resolve time.
ctn_stage1: Option<CtnStage1Recipe>Internal CTN Stage-1 provenance for the marginal-slope z column.
When the marginal-slope z was generated by a transformation-normal
Stage-1 fit, the orchestration layer fills this with the Stage-1 recipe.
Its presence is the sole auto-enable signal for cross-fitted, Neyman-
orthogonal score calibration (#461): the materializer cross-fits the CTN
to produce out-of-fold z and the score-influence Jacobian J, replaces
the raw z with z_oof, and absorbs J as a leakage-projection block in
Stage-2. This is in-process plumbing only — there is no CLI flag, env var,
or feature gate. None ⇒ raw z with the free-warp score_warp
fallback. See CtnStage1Recipe.
scale_dimensions: bool§spatial_optimization: SpatialLengthScaleOptimizationOptionsSpatial length-scale/anisotropy optimization policy shared by every formula family. Front ends must set model-wide spatial knobs here rather than mutating a request after materialization.
adaptive_regularization: Option<bool>Enable exact spatial adaptive regularization for standard formula fits.
None uses the quality-first automatic policy. The current automatic
policy leaves LAREG off unless explicitly requested because the
optimizer’s REML-selected local weights can over-regularize small
high-yield spatial signals.
ridge_lambda: f64§transformation_normal: boolRoute the fit through the transformation-normal family. When set, the
formula terms are treated as the covariate side of the transformation
model and the response basis is built internally. Incompatible with
noise_formula and with Surv(...) responses.
firth: boolEnable Firth bias reduction for standard single-parameter families.
outer_max_iter: Option<usize>Optional cap on the REML/LAML outer smoothing-parameter iterations for
standard formula fits. None uses the production default.
gpu_policy: GpuPolicyGPU backend selection policy. Auto uses supported device kernels for
large workloads, Off pins execution to CPU kernels, and Required fails
loudly when a requested GPU kernel has no compiled backend.
resource_policy: Option<ResourcePolicy>Optional override of the gam_runtime::resource::ResourcePolicy used when
planning spatial bases (TPS / Matern / Duchon) during term construction.
When None, the default-library policy is used.
group_metadata: Option<BTreeMap<String, Value>>Optional per-group metadata supplied by the caller. Fitting ignores this field; saved-model builders pass it through so deployment consumers can recover group provenance.
training_table_kind: StringContainer type of the caller’s training table ("pandas", "polars",
"pyarrow", "numpy", or "unknown" outside a typed table frontend).
Fitting ignores this field; saved-model builders persist it so every
current frontend writes the same complete model schema.
coefficient_groups: Vec<CoefficientGroupSpec>Optional user-defined coefficient groups with separate precision parameters. Group-local priors, including catalog-metadata-informed Gamma precision hyperpriors, are resolved during design setup.
penalty_block_gamma_priors: Vec<(String, f64, f64)>Optional per-existing-penalty-block Gamma(shape, rate) precision hyperpriors keyed by penalty-block label. This is the catalog-metadata-informed-prior hook for models that do not need a new user-defined coefficient group.
latents: Option<Value>Python gamfit.fit(..., latents={...}) configuration. This reaches
the standard formula workflow as an owned latent-coordinate block:
the named smooth’s synthetic covariates are rebuilt from t, and
joint REML optimizes [rho, vec(t)] through latent design hyper-dirs.
analytic_penalties: Option<Value>Python gamfit.fit(..., penalties=[...]) analytic-penalty descriptors,
validated against the declared latent-coordinate blocks before a
standard latent fit starts.
smooth_overrides: Option<Value>gamfit.fit(..., smooths={...}) Python kwarg routed through the FFI
bridge. JSON object keyed by formula symbol (single column name or
comma-joined tuple) → smooth descriptor ({"kind": "duchon", "centers": [[...], ...], ...}). Applied as a post-processing step on
the TermCollectionSpec produced by the formula DSL: each smooth
term whose feature_cols match a registry key has its kind-specific
tunables (centers, knots, kernel hyperparameters) overridden with the
user-supplied values. The single canonical lowering path guarantees
smooths={"x": Duchon(centers=K)} (integer) produces a bit-identical
block spec to writing duchon(x, centers=K) in the formula; only
explicit array-valued centers= differs, routing through
CenterStrategy::UserProvided instead of FarthestPoint/EqualMass.
persistent_warm_start_store: Option<ConfiguredWarmStartStore>Explicit cross-process warm-start capability.
Default None: ordinary fits never consult or write an ambient
machine-global cache. Call
FitConfig::with_persistent_warm_start_root to opt in with a
caller-owned root. The configured capability is lazy and clone-shared,
so validation creates no directories and every standard, survival, and
custom-family owner uses one opened store handle.
spatial_center_counts: Option<Vec<Option<usize>>>Per-smooth spatial center requests maintained by the adaptive
fit→expand→refit loop. Outer None means no loop owns this request, so
raw materialization keeps the ordinary full basis. Some activates the
canonical formula workflow: missing inner entries select the structural
identifiable start and Some(k) requests the next evidence-backed
resolution for that smooth only. This is in-process orchestration state,
never a user knob or environment setting.
precompute_conformal: Option<bool>Whether to precompute the distribution-free conformal substrates (#942
jackknife+, #1098 exact full-conformal) at fit time and persist them on
the saved model. None keeps the historical behaviour of precomputing
whenever the fit is eligible; Some(false) skips both.
The trade-off, measured on y ~ s(x1,k=6) + s(x2,k=6) (#2633): the two
substrates are 94% of a saved Gaussian model at n=20,000 (10.2 MB of
10.85 MB) and grow linearly with the training rows, because they are
per-row. Rebuilding both costs ~5.6 ms, 0.3% of the fit that produced
them. So keeping them buys single-digit milliseconds at roughly half a
kilobyte per training row, forever — turning the flag off yields a ~16x
smaller model (10.85 MB -> ~0.65 MB at n=20,000).
It is opt-OUT rather than opt-in for one reason: rebuilding a substrate needs the training design AND response back, and a saved model deliberately does not carry the training rows. So a model that will be shipped to a host that never sees the training data must keep them, or it cannot produce a conformal interval at all. Turn this off when the caller retains its training data, fits in batch, or never asks for conformal intervals; leave it alone when the model has to stand on its own.
compute_covariance: Option<bool>Whether the fit computes and publishes a coefficient covariance (and the
standard errors derived from it). None keeps each family’s own
default, which for every path that reaches this field today is “yes”;
Some(false) asks for point estimates only.
This exists because it was advice nobody could take (gam#2718). The
bernoulli marginal-slope refusal for a non-StandardNormal latent measure
told callers to “fit without inference if only point estimates are
needed”, while materialize/marginal_slope.rs set
compute_covariance = true unconditionally, so there was no way to
comply. The mechanism was never missing — the latent survival/binary CLI
path has been passing compute_covariance: false in production all
along — only a way for a caller to reach it.
Declining inference is not a way to make a bad covariance acceptable: a
fit that WOULD have withheld its covariance still withholds it and still
declares why (see CovarianceDeclined). This only avoids paying for one
that is never read.
Implementations§
Source§impl FitConfig
impl FitConfig
Sourcepub fn with_persistent_warm_start_root(self, root: impl Into<PathBuf>) -> Self
pub fn with_persistent_warm_start_root(self, root: impl Into<PathBuf>) -> Self
Opt in to cross-process warm starts at the exact supplied root.
The path is neither canonicalized nor relocated through temp/cache discovery. Opening remains lazy until a real fit performs its first persistence operation.
Sourcepub fn resolve(self) -> Result<Self, String>
pub fn resolve(self) -> Result<Self, String>
Normalize and validate the canonical configuration contract.
CLI and JSON layers translate syntax only. Model-family legality and cross-field invariants live here so direct Rust callers cannot bypass the same rules enforced by application front ends.
Sourcepub fn resolved_survival_likelihood(&self) -> &str
pub fn resolved_survival_likelihood(&self) -> &str
The survival likelihood mode this config resolves to for a Surv(...)
fit.
survival_likelihood is None by default — there is no library-side
string default (#2301). An explicit Some(mode) selects that mode; an
unset None resolves to the single canonical default "transformation"
(Royston-Parmar), the same default the CLI documents. This is the ONE
resolution point: the Surv(...) materialization seam, the CLI survival
path, and the pyffi survival path all consult it, so the default lives in
exactly one place. A non-Surv() formula never calls this — Some(_) on
a non-survival response is a typed configuration error rejected by
reject_survival_only_config_for_nonsurvival, and None is unset.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for FitConfig
impl !UnwindSafe for FitConfig
impl Freeze for FitConfig
impl Send for FitConfig
impl Sync for FitConfig
impl Unpin for FitConfig
impl UnsafeUnpin for FitConfig
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,
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
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 moreSource§impl<T> Pointable for T
impl<T> Pointable for T
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.