% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/lgspline.R
\name{lgspline.fit}
\alias{lgspline.fit}
\title{Low-Level Fitting for Lagrangian Smoothing Splines}
\usage{
lgspline.fit(predictors, y = NULL, standardize_response = TRUE,
             standardize_predictors_for_knots = TRUE,
             standardize_expansions_for_fitting = TRUE, family = gaussian(),
             glm_weight_function, schur_correction_function,
             need_dispersion_for_estimation = FALSE,
             dispersion_function,
             K = NULL, custom_knots = NULL, cluster_on_indicators = FALSE,
             make_partition_list = NULL, previously_tuned_penalties = NULL,
             smoothing_spline_penalty = NULL, opt = TRUE, use_custom_bfgs = TRUE,
             delta = NULL, tol = 10*sqrt(.Machine$double.eps),
             tuning_criterion = "loo", gcv_gamma = 1.4,
             initial_wiggle = c(2e-12, 2e-7, 2e-4, 0.2),
             initial_flat = c(0.5, 5), wiggle_penalty = 2e-07,
             flat_ridge_penalty = 0.5, unique_penalty_per_partition = TRUE,
             unique_penalty_per_predictor = TRUE, meta_penalty = 1e-08,
             predictor_penalties = NULL, partition_penalties = NULL,
             include_quadratic_terms = TRUE, include_cubic_terms = TRUE,
             include_quartic_terms = FALSE, include_2way_interactions = TRUE,
             include_3way_interactions = TRUE,
             include_quadratic_interactions = FALSE,
             offset = c(), just_linear_with_interactions = NULL,
             just_linear_without_interactions = NULL,
             exclude_interactions_for = NULL,
             exclude_these_expansions = NULL, custom_basis_fxn = NULL,
             include_constrain_fitted = TRUE,
             include_constrain_first_deriv = TRUE,
             include_constrain_second_deriv = TRUE,
             include_constrain_interactions = TRUE, cl = NULL, chunk_size = NULL,
             parallel_eigen = TRUE, parallel_trace = FALSE, parallel_aga = FALSE,
             parallel_matmult = FALSE, parallel_unconstrained = FALSE,
             parallel_find_neighbors = FALSE, parallel_penalty = FALSE,
             parallel_make_constraint = FALSE,
             unconstrained_fit_fxn = unconstrained_fit_default,
             keep_weighted_Lambda = FALSE, iterate_tune = TRUE,
             iterate_final_fit = TRUE, blockfit = TRUE,
             qp_score_function,
             qp_observations = NULL, qp_Amat = NULL, qp_bvec = NULL, qp_meq = 0,
             qp_positive_derivative = FALSE, qp_negative_derivative = FALSE,
             qp_positive_2ndderivative = FALSE, qp_negative_2ndderivative = FALSE,
             qp_monotonic_increase = FALSE, qp_monotonic_decrease = FALSE,
             qp_range_upper = NULL, qp_range_lower = NULL, qp_Amat_fxn = NULL,
             qp_bvec_fxn = NULL, qp_meq_fxn = NULL, constraint_values = cbind(),
             constraint_vectors = cbind(), return_G = TRUE, return_Ghalf = TRUE,
             return_U = TRUE, estimate_dispersion = TRUE,
             unbias_dispersion = TRUE,
             return_varcovmat = TRUE, exact_varcovmat = FALSE,
             return_lagrange_multipliers = FALSE,
             custom_penalty_mat = NULL,
             cluster_args = c(custom_centers = NA, nstart = 10),
             dummy_dividor = 1.2345672152894e-22,
             dummy_adder = 2.234567210529e-18,
             verbose = FALSE, verbose_tune = FALSE,
             dummy_fit = FALSE, auto_encode_factors = TRUE,
             observation_weights = NULL, do_not_cluster_on_these = c(),
             neighbor_tolerance = 1 + 1e-16, no_intercept = FALSE,
             VhalfInv = NULL, Vhalf = NULL, include_warnings = TRUE,
             og_cols = NULL,
             factor_groups = NULL, ...)
}
\arguments{
\item{predictors}{Numeric matrix or data frame of predictor variables on the
low-level input scale expected by \code{lgspline.fit}. Unlike
\code{\link{lgspline}}, this interface does not parse formulas or a
separate \code{data} argument.}

\item{y}{Default: NULL. Numeric response variable vector.}

\item{standardize_response}{Default: TRUE. Logical indicator controlling whether
the response variable should be centered and scaled before model fitting. Only
offered for identity link functions.}

\item{standardize_predictors_for_knots}{Default: TRUE. Logical flag controlling
whether predictors are internally standardized for partitioning / knot
placement. The exact transformation is handled inside
\code{\link{make_partitions}} and depends on the effective clustering
dimension.}

\item{standardize_expansions_for_fitting}{Default: TRUE. Logical switch to
standardize polynomial basis expansions during model fitting. Design matrices,
variance-covariance matrices, and coefficients are backtransformed after fitting.
\eqn{\mathbf{U}} and \eqn{\mathbf{G}} remain on the transformed scale;
\code{B_raw} corresponds to coefficients on the expansion-standardized scale.}

\item{family}{Default: \code{gaussian()}. GLM family specifying the error distribution
and link function. Minimally requires: family name, link name, linkfun, linkinv,
variance.}

\item{glm_weight_function}{Default: function returning \code{family$variance(mu)},
optionally multiplied by \code{observation_weights}. Codes the mean-variance
relationship (the diagonal \eqn{\mathbf{W}} matrix) used for updating
\eqn{\mathbf{G}} after obtaining constrained estimates.}

\item{schur_correction_function}{Default: function returning list of zeros.
Computes Schur complements \eqn{\mathbf{S}} added to \eqn{\mathbf{G}}:
\eqn{\mathbf{G}^{*} = (\mathbf{G}^{-1} + \mathbf{S})^{-1}}.}

\item{need_dispersion_for_estimation}{Default: FALSE. Logical indicator specifying
whether a dispersion parameter is required for coefficient estimation (e.g.
Weibull AFT).}

\item{dispersion_function}{Default: function returning mean squared residuals.
Custom function for estimating the exponential dispersion parameter.}

\item{K}{Default: NULL. Integer specifying the number of knot locations. Intuitively,
total partitions minus 1.}

\item{custom_knots}{Default: NULL. Optional matrix providing user-specified knot
locations in 1-D.}

\item{cluster_on_indicators}{Default: FALSE. Logical flag for whether indicator
variables should be used for clustering knot locations.}

\item{make_partition_list}{Default: NULL. Optional list allowing direct specification
of custom partition assignments. The \code{make_partition_list} returned by one
model can be supplied here to reuse knot locations.}

\item{previously_tuned_penalties}{Default: NULL. Optional list of pre-computed penalty
components from a previous model fit.}

\item{smoothing_spline_penalty}{Default: NULL. Optional custom smoothing spline penalty
matrix.}

\item{opt}{Default: TRUE. Logical switch controlling automatic penalty optimization.}

\item{use_custom_bfgs}{Default: TRUE. Selects between a native damped-BFGS
implementation with closed-form gradients or base R's BFGS with finite-difference
gradients. The native path is usually faster, while the finite-difference
fallback can be preferable when tuning under exact LOO and the leverage
derivative is numerically noisy.}

\item{delta}{Default: NULL. Numeric pseudocount for stabilizing optimization in
non-identity link function scenarios.}

\item{tol}{Default: \code{10*sqrt(.Machine$double.eps)}. Numeric convergence tolerance.}

\item{tuning_criterion}{Default: \code{"loo"}. Character scalar selecting the
tuning criterion. Use \code{"loo"} for exact leave-one-out on the transformed
tuning problem, or \code{"gcv"} for the generalized cross-validation
criterion. The LOO path computes the needed hat-matrix diagonal exactly
from blockwise constrained-\eqn{\mathbf{G}} quantities, without explicitly
forming the full projection matrix or full hat matrix. In empirical
diagnostics, the observation-wise derivative of the LOO leverage term can
be numerically delicate even when the overall tuning criterion and fitted
penalties remain well behaved; users who prefer a more conservative
optimization path can set \code{use_custom_bfgs = FALSE}. Shared wiggle
and flat tuning directions are differentiated directly, while optional
predictor- and partition-specific penalties continue to use a lower-cost
ratio approximation. For very large samples, generalized cross-validation
is often the more practical choice; as a rough guideline, \code{"gcv"}
is recommended once the sample size is above about 250,000.}

\item{gcv_gamma}{Default: 1.4. Numeric scalar, at least 1, used only when
\code{tuning_criterion = "gcv"}. Multiplies the effective degrees of freedom
in the GCV denominator during automatic penalty tuning. It is accepted but
ignored when \code{tuning_criterion = "loo"}.}

\item{initial_wiggle}{Default: \code{c(2e-12, 2e-7, 2e-4, 0.2)}. Numeric vector of
initial grid points for wiggle penalty optimization, on the raw (non-negative) scale.}

\item{initial_flat}{Default: \code{c(0.5, 5)}. Numeric vector of initial grid points
for ridge penalty optimization, on the raw scale (ratio of ridge to wiggle).}

\item{wiggle_penalty}{Default: 2e-7. Numeric penalty on the integrated squared second
derivative, governing function smoothness.}

\item{flat_ridge_penalty}{Default: 0.5. Numeric flat ridge penalty for intercepts and
linear terms only. Multiplied by \code{wiggle_penalty} to obtain total ridge penalty.}

\item{unique_penalty_per_partition}{Default: TRUE. Logical flag allowing penalty
magnitude to differ across partitions.}

\item{unique_penalty_per_predictor}{Default: TRUE. Logical flag allowing penalty
magnitude to differ between predictors.}

\item{meta_penalty}{Default: 1e-8. Numeric regularization coefficient for
predictor- and partition-specific penalties during tuning. On the raw scale,
the implemented meta-penalty shrinks these penalty multipliers toward 1; the
wiggle penalty receives only a tiny stabilizing penalty by default.}

\item{predictor_penalties}{Default: NULL. Optional vector of custom penalties per
predictor, on the raw (positive) scale.}

\item{partition_penalties}{Default: NULL. Optional vector of custom penalties per
partition, on the raw (positive) scale.}

\item{include_quadratic_terms}{Default: TRUE. Logical switch to include squared
predictor terms.}

\item{include_cubic_terms}{Default: TRUE. Logical switch to include cubic predictor
terms.}

\item{include_quartic_terms}{Default: FALSE. Logical switch to include quartic
predictor terms at this low-level interface.}

\item{include_2way_interactions}{Default: TRUE. Logical switch for linear two-way
interactions.}

\item{include_3way_interactions}{Default: TRUE. Logical switch for three-way
interactions.}

\item{include_quadratic_interactions}{Default: FALSE. Logical switch for
linear-quadratic interaction terms.}

\item{offset}{Default: Empty vector. Column indices/names to include as offsets.
Coefficients for offset terms are automatically constrained to 1.}

\item{just_linear_with_interactions}{Default: NULL. Integer or character vector
specifying predictors to retain as linear terms while still allowing
interactions.}

\item{just_linear_without_interactions}{Default: NULL. Integer or character
vector specifying predictors to retain only as linear terms without
interactions. Eligible for blockfitting.}

\item{exclude_interactions_for}{Default: NULL. Integer or character vector of
predictors to exclude from all interaction terms.}

\item{exclude_these_expansions}{Default: NULL. Character vector of basis expansions to
exclude. Named columns of data, or in the form \code{"_1_"}, \code{"_2_"},
\code{"_1_x_2_"}, \code{"_2_^2"} etc.}

\item{custom_basis_fxn}{Default: NULL. Optional user-defined function for custom basis
expansions. See \code{\link{get_polynomial_expansions}}.}

\item{include_constrain_fitted}{Default: TRUE. Logical switch to constrain fitted
values at knot points.}

\item{include_constrain_first_deriv}{Default: TRUE. Logical switch to constrain first
derivatives at knot points.}

\item{include_constrain_second_deriv}{Default: TRUE. Logical switch to constrain second
derivatives at knot points.}

\item{include_constrain_interactions}{Default: TRUE. Logical switch to constrain
interaction terms at knot points.}

\item{cl}{Default: NULL. Parallel processing cluster object
(use \code{parallel::makeCluster()}).}

\item{chunk_size}{Default: NULL. Integer specifying custom chunk size for parallel
processing.}

\item{parallel_eigen}{Default: TRUE. Logical flag for parallel eigenvalue decomposition.}

\item{parallel_trace}{Default: FALSE. Logical flag for parallel trace computation.}

\item{parallel_aga}{Default: FALSE. Logical flag for parallel \eqn{\mathbf{G}} and
\eqn{\mathbf{A}} matrix operations.}

\item{parallel_matmult}{Default: FALSE. Logical flag for parallel block-diagonal matrix
multiplication.}

\item{parallel_unconstrained}{Default: FALSE. Logical flag for parallel
unconstrained MLE for non-identity-link-Gaussian models.}

\item{parallel_find_neighbors}{Default: FALSE. Logical flag for parallel neighbor
identification.}

\item{parallel_penalty}{Default: FALSE. Logical flag for parallel penalty matrix
construction.}

\item{parallel_make_constraint}{Default: FALSE. Logical flag for parallel constraint
matrix generation.}

\item{unconstrained_fit_fxn}{Default: \code{\link{unconstrained_fit_default}}.
Custom function for fitting unconstrained models per partition.}

\item{keep_weighted_Lambda}{Default: FALSE. Logical flag to retain GLM weights in
penalty constraints using Tikhonov parameterization. Advised for non-canonical GLMs.}

\item{iterate_tune}{Default: TRUE. Logical switch for iterative optimization during
penalty tuning.}

\item{iterate_final_fit}{Default: TRUE. Logical switch for iterative optimization in
final model fitting.}

\item{blockfit}{Default: TRUE. Logical switch for backfitting with mixed spline and
non-interactive linear terms. Requires flat columns, \code{K > 0}, and no active
correlation structure. Falls back to \code{get_B} on failure.}

\item{qp_score_function}{Default: \eqn{\mathbf{X}^{\top}(\mathbf{y} - \boldsymbol{\mu})}.
Score function for quadratic programming, blockfit, and GEE formulations.
Accepts arguments \code{"X, y, mu, order_list, dispersion, VhalfInv,
observation_weights, ..."}.}

\item{qp_observations}{Default: NULL. Numeric vector of observation indices
at which built-in QP constraints are evaluated. Useful for reducing the
size of the constrained system.}

\item{qp_Amat}{Default: NULL. Optional pre-built QP constraint matrix.
In the current pipeline its presence marks QP handling as active, but the
built-in constructor does not merge it into the assembled constraint set;
use \code{qp_Amat_fxn} for custom assembled constraints.}

\item{qp_bvec}{Default: NULL. Optional pre-built QP right-hand side paired
with \code{qp_Amat}. Like \code{qp_Amat}, it is currently treated as an
advanced placeholder rather than merged into the built-in constructor.}

\item{qp_meq}{Default: 0. Optional number of equality constraints paired
with \code{qp_Amat}. Like \code{qp_Amat}, it is currently treated as an
advanced placeholder rather than merged into the built-in constructor.}

\item{qp_positive_derivative}{Default: FALSE. Constrain function to have positive first derivatives. Accepts: \code{FALSE} (no constraint), \code{TRUE} (all predictors), or a character/integer vector naming specific predictor variables to constrain. For example, \code{qp_positive_derivative = "Dose"} constrains only the Dose variable, while \code{qp_positive_derivative = c(1, 3)} constrains columns 1 and 3 of the predictor matrix.}

\item{qp_negative_derivative}{Default: FALSE. Constrain function to have negative first derivatives. Same input types as \code{qp_positive_derivative}. Can be used simultaneously with \code{qp_positive_derivative} on different variables.}

\item{qp_positive_2ndderivative}{Default: FALSE. Constrain function to have positive (convex) second derivatives. Same input types as \code{qp_positive_derivative}.}

\item{qp_negative_2ndderivative}{Default: FALSE. Constrain function to have negative (concave) second derivatives. Same input types as \code{qp_positive_derivative}.}

\item{qp_monotonic_increase}{Default: FALSE. Logical only. Constrain fitted values to be monotonically increasing in observation order.}

\item{qp_monotonic_decrease}{Default: FALSE. Logical only. Constrain fitted values to be monotonically decreasing in observation order.}

\item{qp_range_upper}{Default: NULL. Numeric upper bound for constrained fitted values.}

\item{qp_range_lower}{Default: NULL. Numeric lower bound for constrained fitted values.}

\item{qp_Amat_fxn}{Default: NULL. Custom function generating Amat.}

\item{qp_bvec_fxn}{Default: NULL. Custom function generating bvec.}

\item{qp_meq_fxn}{Default: NULL. Custom function generating meq.}

\item{constraint_values}{Default: \code{cbind()}. Optional matrix encoding
nonzero equality targets paired with \code{constraint_vectors}. When left
empty, added equality constraints are treated as homogeneous.}

\item{constraint_vectors}{Default: \code{cbind()}. Optional matrix of
user-supplied equality-constraint vectors, appended to the internally
generated smoothness constraints.}

\item{return_G}{Default: TRUE. Logical switch to return the unscaled unconstrained
variance-covariance matrix \eqn{\mathbf{G}}.}

\item{return_Ghalf}{Default: TRUE. Logical switch to return
\eqn{\mathbf{G}^{1/2}}.}

\item{return_U}{Default: TRUE. Logical switch to return the constraint projection
matrix \eqn{\mathbf{U}}.}

\item{estimate_dispersion}{Default: TRUE. Logical flag to estimate dispersion after
fitting.}

\item{unbias_dispersion}{Default: TRUE. Logical switch to multiply
dispersion by \eqn{N/(N - \mathrm{trace}(\mathbf{H}))}. Unlike
\code{\link{lgspline}}, no wrapper-level auto-resolution is performed here.}

\item{return_varcovmat}{Default: TRUE. Logical switch to return the variance-covariance
matrix of estimated coefficients. Needed for Wald inference.}

\item{exact_varcovmat}{Default: FALSE. Logical switch to replace the default
asymptotic (Bayesian posterior) variance-covariance matrix with the exact
frequentist variance-covariance matrix of the constrained estimator. The
asymptotic version uses the Hessian of
the penalized log-likelihood:
\eqn{\tilde{\sigma}^{2}\mathbf{U}\mathbf{G}\mathbf{U}^{\top}}.
The exact version additionally corrects for the penalty's contribution as a shrinkage
prior, giving:
\deqn{\tilde{\sigma}^{2}\mathbf{U}\mathbf{G}\mathbf{U}^{\top}
      - \tilde{\sigma}^{2}\mathbf{U}\mathbf{G}\boldsymbol{\Lambda}\mathbf{G}\mathbf{U}^{\top}}
When a correlation structure is present (\code{VhalfInv} non-NULL),
\eqn{\mathbf{G}_{\mathrm{correct}}} replaces the block-diagonal \eqn{\mathbf{G}}.
For Gaussian identity link (with or without correlation structure), the result is
the exact variance-covariance matrix of the constrained estimate.
The returned object still stores the result in \code{varcovmat}. Requires
\code{return_varcovmat = TRUE}.}

\item{return_lagrange_multipliers}{Default: FALSE. Logical switch to return the
Lagrangian multiplier vector.}

\item{custom_penalty_mat}{Default: NULL. Optional \eqn{p \times p} custom penalty
matrix for individual partitions, replacing the default ridge on linear/intercept
terms. Run with \code{dummy_fit = TRUE} first to inspect expansion structure.}

\item{cluster_args}{Default: \code{c(custom_centers = NA, nstart = 10)}. Named
vector of arguments controlling clustering. If the first argument is not
\code{NA}, it is treated as custom cluster centers (typically an
\eqn{(K+1) \times q} matrix). Otherwise, default k-means is used.}

\item{dummy_dividor}{Default: 0.00000000000000000000012345672152894. Small numeric
constant to prevent division by zero.}

\item{dummy_adder}{Default: 0.000000000000000002234567210529. Small numeric constant
to prevent division by zero.}

\item{verbose}{Default: FALSE. Logical flag to print general progress messages.}

\item{verbose_tune}{Default: FALSE. Logical flag to print detailed progress during
penalty tuning.}

\item{dummy_fit}{Default: FALSE. Runs the full pipeline but sets coefficients to zero,
allowing inspection of design matrix structure, penalty matrices, and partitioning.
Replaces the deprecated \code{expansions_only} argument.}

\item{auto_encode_factors}{Default: TRUE. Compatibility flag carried through
from higher-level preprocessing. Direct calls to \code{lgspline.fit}
should usually supply already encoded predictors and use
\code{factor_groups} when sum-to-zero constraints are needed.}

\item{observation_weights}{Default: NULL. Numeric vector of observation-specific
weights for generalized least squares estimation.}

\item{do_not_cluster_on_these}{Default: \code{c()}. Predictor columns to exclude from
clustering. Accepts numeric column indices or character column names.}

\item{neighbor_tolerance}{Default: \code{1 + 1e-16}. Numeric tolerance for
determining neighboring partitions using k-means clustering. Intended for
internal use.}

\item{no_intercept}{Default: FALSE. Logical flag to constrain intercept to 0.
Formulas with \code{"0+"} set this to TRUE automatically.}

\item{VhalfInv}{Default: NULL. Fixed custom \eqn{N \times N} square-root-inverse
covariance matrix \eqn{\mathbf{V}^{-1/2}}. Triggers GLS with known covariance.
Post-fit inference recomputed from whitened Gram matrices.}

\item{Vhalf}{Default: NULL. Fixed custom \eqn{N \times N} square-root covariance
\eqn{\mathbf{V}^{1/2}}. Computed as inverse of \code{VhalfInv} if not supplied.}

\item{include_warnings}{Default: TRUE. Logical switch to control display of warnings.}

\item{og_cols}{Default: NULL. Original predictor names}

\item{factor_groups}{Named list mapping original factor variable names to
integer vectors of their corresponding one-hot indicator column positions
within the predictor matrix. Each element enforces a sum-to-zero equality
constraint on the linear-term coefficients of its indicator columns within
every partition, ensuring identifiability when all factor levels are
included without a reference/dropped level. For a group with indicator
columns at positions \code{j1, j2, ..., jm}, the constraint is
\eqn{\sum_{i=1}^{m} \beta_{ji,k} = 0} for each partition \eqn{k}.
Groups with fewer than two resolved positions are silently ignored.
Populated automatically by \code{\link{process_input}} when
\code{auto_encode_factors = TRUE}; users calling \code{lgspline.fit}
directly should construct this list manually when passing one-hot encoded
predictors without a reference level. Default \code{NULL} (no
sum-to-zero constraints imposed).}

\item{...}{Additional arguments passed to the unconstrained model fitting function.}
}
\value{
A list containing the fitted model components, forming the core
structure used internally by \code{\link{lgspline}} and its associated methods.
This function is primarily intended for internal use or advanced users needing
direct access to fitting components. The returned list contains numerous elements,
typically including:
\describe{
  \item{y}{The original response vector provided.}
  \item{ytilde}{The fitted values on the original response scale. Set to
    \code{rep(0, N)} when \code{dummy_fit = TRUE}.}
  \item{X}{A list, with each element the design matrix (\eqn{\mathbf{X}_{k}})
    for partition k, on the unstandardized expansion scale.}
  \item{A}{The constraint matrix (\eqn{\mathbf{A}}) encoding smoothness and
    any other linear equality constraints. Reduced to linearly independent
    columns via pivoted QR decomposition.}
  \item{B}{A list of the final fitted coefficient vectors
    (\eqn{\boldsymbol{\beta}_{k}}) for each partition k, on the original
    predictor/response scale.}
  \item{B_raw}{A list of fitted coefficient vectors on the internally
    standardized scale used during fitting.}
  \item{K, p, q, P, N}{Key dimensions: number of internal knots (K), basis
    functions per partition (p), original predictors (q), total coefficients
    (P), and sample size (N).}
  \item{penalties}{A list containing the final penalty components used
    (e.g., \code{Lambda}, \code{L1}, \code{L2}, \code{L_predictor_list},
    \code{L_partition_list}). See \code{\link{compute_Lambda}}.}
  \item{knot_scale_transf, knot_scale_inv_transf}{Functions to transform
    predictors to/from the scale used for knot placement.}
  \item{knots}{Matrix or vector of knot locations on the original predictor
    scale (NULL if K=0 or q > 1).}
  \item{partition_codes}{Vector assigning each original observation to a partition.}
  \item{partition_bounds}{Internal representation of partition boundaries.}
  \item{make_partition_list}{List containing centers, knot midpoints, neighbor
    info, and assignment function from partitioning (NULL if K=0 or 1D).
    See \code{\link{make_partitions}}.}
  \item{knot_expand_function, assign_partition}{Internal functions for
    partitioning data. See \code{\link{knot_expand_list}}.}
  \item{predict}{The primary function embedded in the object for generating
    predictions on new data. For multi-predictor models,
    \code{take_first_derivatives = TRUE} returns derivatives as a named list
    of per-variable derivative vectors rather than a concatenated vector.
    See \code{\link{predict.lgspline}}.}
  \item{family}{The \code{\link[stats]{family}} object or custom list used.}
  \item{estimate_dispersion, unbias_dispersion}{Logical flags related to
    dispersion estimation settings.}
  \item{sigmasq_tilde}{The estimated (or fixed) dispersion parameter
    \eqn{\tilde{\sigma}^{2}}. For Gaussian identity fits with
    \code{VhalfInv} non-\code{NULL}, this is computed from whitened
    residuals \eqn{\mathbf{V}^{-1/2}(\mathbf{y} - \hat{\mathbf{y}})},
    multiplied by the observation weights and the optional
    bias-correction factor. When \code{estimate_dispersion = FALSE},
    set to 1. Omitted when \code{dummy_fit = TRUE}.}
  \item{backtransform_coefficients, forwtransform_coefficients}{Functions to
    convert coefficients between standardized and original scales.}
  \item{mean_y, sd_y}{Mean and standard deviation used for standardizing
    the response.}
  \item{og_order, order_list}{Information mapping original data order to
    partitioned order.}
  \item{constraint_values, constraint_vectors}{User-supplied additional linear
    equality constraints.}
  \item{expansion_scales}{Scaling factors applied to basis expansions during
    fitting (if \code{standardize_expansions_for_fitting = TRUE}).}
  \item{take_derivative, take_interaction_2ndderivative,
    get_all_derivatives_insample}{Functions related to computing derivatives
    of the fitted spline.}
  \item{numerics, power1_cols, ..., nonspline_cols}{Integer vectors storing
    column indices identifying different types of terms in the basis expansion.}
  \item{return_varcovmat}{Logical indicating if variance matrix calculation
    was requested.}
  \item{exact_varcovmat}{Not returned as a standalone component; this
    argument only controls whether \code{varcovmat}, when requested, is
    left as the default asymptotic/Laplace version or replaced by the
    exact frequentist correction available for Gaussian identity fits.}
  \item{raw_expansion_names}{Original generated names for basis expansion
    columns (before potential renaming if input predictors had names).}
  \item{std_X, unstd_X}{Functions to standardize/unstandardize design matrices
    according to \code{expansion_scales}.}
  \item{parallel_cluster_supplied}{Logical indicating if a parallel cluster
    was used.}
  \item{weights}{The original observation weights provided (potentially
    reformatted).}
  \item{VhalfInv}{The fixed \eqn{\mathbf{V}^{-1/2}} matrix if supplied.}
  \item{quadprog_list}{List containing components related to quadratic
    programming constraints, if used.}
  \item{G}{List of unscaled variance-covariance matrices
    \eqn{\mathbf{G}_{k}} per partition, returned if \code{return_G = TRUE}.
    When \code{VhalfInv} is non-\code{NULL}, recomputed from whitened Gram
    matrices. Omitted when \code{dummy_fit = TRUE}.}
  \item{Ghalf}{List of \eqn{\mathbf{G}_{k}^{1/2}} matrices, returned if
    \code{return_Ghalf = TRUE}. When \code{VhalfInv} is non-\code{NULL},
    the full \eqn{\mathbf{G}_{\mathrm{correct}}^{1/2}} is used for
    posterior draws and variance-covariance computation.
    Omitted when \code{dummy_fit = TRUE}.}
  \item{U}{Constraint projection matrix \eqn{\mathbf{U}}, returned if
    \code{return_U = TRUE}. Omitted when \code{dummy_fit = TRUE}.}
  \item{trace_XUGX}{The effective degrees-of-freedom trace term.
    When \code{VhalfInv} is non-\code{NULL}, it is computed from the
    full penalized GLS information rather than the block-diagonal
    approximation. Omitted when \code{dummy_fit = TRUE}.}
  \item{varcovmat}{The final variance-covariance matrix of the estimated
    coefficients. Computed via the outer-product form
    \eqn{\sigma^{2}(\mathbf{U}\mathbf{G}^{1/2})(\mathbf{U}\mathbf{G}^{1/2})^{\top}}
    for numerical stability. When \code{VhalfInv} is non-\code{NULL}, uses
    the full \eqn{\mathbf{G}_{\mathrm{correct}}^{1/2}} in place of
    block-diagonal \eqn{\mathbf{G}^{1/2}}. Returned if
    \code{return_varcovmat = TRUE}. By default this is the asymptotic
    (Laplace/posterior) variance-covariance matrix; when
    \code{exact_varcovmat = TRUE}, it is replaced in-place by the exact
    frequentist correction available for Gaussian identity fits.
    Omitted when \code{dummy_fit = TRUE}.}
  \item{lagrange_multipliers}{Vector of Lagrangian multipliers if
    \code{return_lagrange_multipliers = TRUE}. For equality-only fits these
    follow the formulation
    \eqn{(\mathbf{A}^{\top}\mathbf{G}\mathbf{A})^{-1}\mathbf{A}^{\top}(\hat{\boldsymbol{\beta}} - \boldsymbol{\beta_0})}.
    When quadratic-programming constraints are active they are taken
    directly from \code{solve.QP} and therefore refer to the combined
    equality/inequality constraint system. \code{NULL} if no constraints
    are active}.
}
Note that the exact components returned depend heavily on the function
arguments (e.g., values of \code{return_G}, \code{return_varcovmat}, etc.)
and whether \code{dummy_fit = TRUE}.
}
\description{
The core function for fitting Lagrangian smoothing splines with
less user-friendliness. Called internally by \code{\link{lgspline}} after
formula parsing, factor encoding, and correlation-structure setup.
}
\details{
\code{lgspline.fit} performs the following steps:
\enumerate{
  \item Polynomial expansion and predictor standardization.
  \item Knot placement and partitioning (k-means or custom).
  \item Constraint matrix \eqn{\mathbf{A}} construction. Only a linearly
        independent subset of columns is retained via pivoted QR decomposition.
  \item Penalty tuning via exact leave-one-out by default, or generalized
        cross-validation when \code{tuning_criterion = "gcv"}, or use of
        previously tuned penalties.
  \item Final coefficient estimation via one of three paths:
        \itemize{
          \item \strong{Blockfit option} (when \code{blockfit = TRUE},
                flat columns are non-empty, \code{K > 0}, and no correlation
                structure): Routes through \code{blockfit_solve} for
                backfitting with mixed spline and non-interactive linear terms.
                Falls back to \code{get_B} on failure.
          \item \strong{Standard \code{get_B}} path: Three internal
                computational paths: GEE (damped SQP with correlation
                structures), Gaussian identity (closed-form OLS projection),
                and general GLM (unconstrained fit + Lagrangian projection
                with optional IRLS loop).
        }
  \item Post-fit inference: \eqn{\mathbf{U}}, trace, dispersion,
        variance-covariance matrix, and optionally Lagrange multipliers.
        When \code{VhalfInv} is non-\code{NULL}, these are computed from
        the whitened Gram matrices
        \eqn{\mathbf{X}^{\top}\mathbf{V}^{-1}\mathbf{X}} via the full
        penalized GLS information
        \eqn{\mathbf{G}_{\mathrm{correct}} =
        (\mathbf{X}^{\top}\mathbf{V}^{-1}\mathbf{X} +
        \boldsymbol{\Lambda})^{-1}}.
}

\strong{Dummy fit.} When \code{dummy_fit = TRUE}, an early-return path
skips the expensive fitting steps (\code{compute_G_eigen}, \code{get_B},
trace computation, variance-covariance matrix) while retaining all
penalty, partitioning, and design matrix information. Coefficients are
set to zero. This replaces the deprecated \code{expansions_only} argument.
}
\keyword{internal}
