% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/get_B.R
\name{get_B}
\alias{get_B}
\title{Compute Constrained GLM Coefficient Estimates via Lagrangian Multipliers}
\usage{
get_B(
  X,
  X_gram,
  Lambda,
  keep_weighted_Lambda,
  unique_penalty_per_partition,
  L_partition_list,
  A,
  Xy,
  y,
  K,
  p_expansions,
  R_constraints,
  Ghalf,
  GhalfInv,
  parallel_eigen,
  parallel_aga,
  parallel_matmult,
  parallel_unconstrained,
  cl,
  chunk_size,
  num_chunks,
  rem_chunks,
  family,
  unconstrained_fit_fxn,
  iterate,
  qp_score_function,
  quadprog,
  qp_Amat,
  qp_bvec,
  qp_meq,
  prevB = NULL,
  prevUnconB = NULL,
  iter_count = 0,
  prev_diff = Inf,
  tol,
  constraint_value_vectors,
  order_list,
  glm_weight_function,
  schur_correction_function,
  need_dispersion_for_estimation,
  dispersion_function,
  observation_weights,
  homogenous_weights,
  return_G_getB,
  blockfit,
  just_linear_without_interactions,
  Vhalf,
  VhalfInv,
  ...
)
}
\arguments{
\item{X}{List of length \eqn{K+1}; partition-specific design matrices.}

\item{X_gram}{List of Gram matrices by partition.}

\item{Lambda}{Combined penalty matrix.}

\item{keep_weighted_Lambda}{Logical.}

\item{unique_penalty_per_partition}{Logical.}

\item{L_partition_list}{List of partition-specific penalty matrices.}

\item{A}{Constraint matrix \eqn{\mathbf{A}} (\eqn{P \times R}).}

\item{Xy}{List of cross-products by partition.}

\item{y}{List of response vectors by partition.}

\item{K}{Integer; number of interior knots.}

\item{p_expansions}{Integer; basis terms per partition.}

\item{R_constraints}{Integer; columns of \eqn{\mathbf{A}}.}

\item{Ghalf}{List of \eqn{\mathbf{G}^{1/2}_k} matrices.}

\item{GhalfInv}{List of \eqn{\mathbf{G}^{-1/2}_k} matrices.}

\item{parallel_eigen, parallel_aga, parallel_matmult, parallel_unconstrained}{Logical flags.}

\item{cl}{Cluster object.}

\item{chunk_size, num_chunks, rem_chunks}{Parallel distribution parameters.}

\item{family}{GLM family object.}

\item{unconstrained_fit_fxn}{Partition-wise unconstrained estimator.}

\item{iterate}{Logical; iterate for non-canonical links.}

\item{qp_score_function}{Score function for QP steps.}

\item{quadprog}{Logical; use \code{quadprog::solve.QP} for inequality
constraints.}

\item{qp_Amat, qp_bvec, qp_meq}{Inequality constraint specification
\eqn{\mathbf{C}^{\top}\boldsymbol{\beta} \succeq \mathbf{c}}.}

\item{prevB, prevUnconB, iter_count, prev_diff}{Retired; ignored.}

\item{tol}{Convergence tolerance.}

\item{constraint_value_vectors}{List encoding nonzero RHS
\eqn{\mathbf{A}^{\top}\boldsymbol{\beta} = \mathbf{c}}.}

\item{order_list}{Partition-to-data index mapping.}

\item{glm_weight_function}{Function computing working weights.}

\item{schur_correction_function}{Function computing Schur corrections.}

\item{need_dispersion_for_estimation}{Logical.}

\item{dispersion_function}{Dispersion estimator.}

\item{observation_weights}{List of observation weights by partition.}

\item{homogenous_weights}{Logical.}

\item{return_G_getB}{Logical; return \eqn{\mathbf{G}},
\eqn{\mathbf{G}^{1/2}}, \eqn{\mathbf{G}^{-1/2}} per partition.}

\item{blockfit, just_linear_without_interactions}{Retired; retained for
call-site compatibility.}

\item{Vhalf, VhalfInv}{Square root and inverse square root of the
working correlation matrix in the original observation ordering.
When both are non-\code{NULL}, dispatches to Path 1; \code{VhalfInv}
is permuted internally to partition ordering via \code{order_list}.}

\item{...}{Passed to fitting, weight, correction, and dispersion
functions.}
}
\value{
If \code{return_G_getB = FALSE}: a list with \code{B} (coefficient
column vectors by partition) and \code{qp_info}.

If \code{return_G_getB = TRUE}: a list with elements:
\describe{
  \item{B}{List of constrained coefficient column vectors
    \eqn{\tilde{\boldsymbol{\beta}}_k} by partition.}
  \item{G_list}{List with \code{G}, \code{Ghalf}, \code{GhalfInv},
    each a list of \eqn{K+1} matrices.}
  \item{qp_info}{QP or active-set metadata, including Lagrangian
    multipliers and active-constraint information when available, or
    \code{NULL}.}
}
}
\description{
Core estimation function for Lagrangian multiplier smoothing splines.
Computes penalized coefficient estimates subject to smoothness constraints
(continuity and derivative matching at knots) and optional user-supplied
linear equality or inequality constraints. Dispatches to one of three
computational paths depending on the model structure:

\bold{Path 1. GEE (correlation structure present):}
When both \code{Vhalf} and \code{VhalfInv} are provided, the full
\eqn{N \times P} whitened design
\eqn{\mathbf{X}^{*} = \mathbf{V}_{\mathrm{perm}}^{-1/2}\mathbf{X}} is used
after permuting observations to partition ordering via \code{order_list}.
For structured correlation, the solver tries the supplement's
decomposition
\eqn{\mathbf{G}^{-1} =
\mathbf{G}_{\mathrm{on}}^{-1} + \mathbf{G}_{\mathrm{off}}^{-1}}
with
\eqn{\mathbf{G}_{\mathrm{off}}^{-1} = \mathbf{E}\mathbf{J}\mathbf{E}^{\top}}.
This gives a Woodbury path with cost \eqn{O(Kp^3 + Pr^2)} when the
cross-partition rank \eqn{r} is small; otherwise the dense
\eqn{O(P^3)} path is used.
Two sub-paths:
\itemize{
  \item \bold{Path 1a.} Gaussian identity + GEE.
    See \code{\link{.get_B_gee_gaussian}} (dense) and
    \code{\link{.get_B_gee_woodbury}} (accelerated).
  \item \bold{Path 1b.} Non-Gaussian GEE.
    See \code{\link{.get_B_gee_glm}} (dense) and
    \code{\link{.get_B_gee_glm_woodbury}} (accelerated).
}

\bold{Path 2. Gaussian identity link, no correlation:}
Unconstrained estimate \eqn{\hat{\boldsymbol{\beta}}_k =
\mathbf{G}_k\mathbf{X}_k^{\top}\mathbf{y}_k} per partition, then a
single Lagrangian projection. See \code{\link{.get_B_gaussian_nocorr}}.

\bold{Path 3. Non-Gaussian GLM, no correlation:}
Partition-wise unconstrained estimates via Newton-Raphson, then
Lagrangian projection. See \code{\link{.get_B_glm_nocorr}}.

\bold{Inequality constraint handling:}
When inequality constraints \eqn{\mathbf{C}^{\top}\boldsymbol{\beta}
\succeq \mathbf{c}} are present, the sparsity pattern of
\eqn{\mathbf{C}} is inspected automatically. If every constraint
column has nonzeros in only a single partition block (block-separable),
a partition-wise active-set method is used at cost
\eqn{O(Kp^3)} per iteration. If any constraint spans multiple
partition blocks (e.g.\ cross-knot monotonicity), the dense
\code{quadprog::solve.QP} SQP fallback is invoked.
}
\keyword{internal}
