% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/clsp.R
\name{clsp}
\alias{clsp}
\title{Convex Least Squares Programming (CLSP) estimator.}
\usage{
clsp(
  problem = "",
  C = NULL,
  S = NULL,
  M = NULL,
  b = NULL,
  m = NULL,
  p = NULL,
  i = 1L,
  j = 1L,
  zero_diagonal = FALSE,
  r = 1L,
  Z = NULL,
  rcond = FALSE,
  tolerance = NULL,
  iteration_limit = NULL,
  final = TRUE,
  alpha = NULL,
  cond_tolerance = NULL,
  ...
)
}
\arguments{
\item{problem}{character scalar, optional
Structural template for matrix construction. One of:
\itemize{
\item \code{'ap'}   or \code{'tm'}: allocation or tabular matrix problem.
\item \code{'cmls'} or \code{'rp'}: constrained modular least squares or RP-type.
\item \code{''}     or other:  general CLSP problems (user-defined
\eqn{\boldsymbol{C}} and/or \eqn{\boldsymbol{M}}).
}}

\item{C, S, M}{numeric matrix or \code{NULL}
Blocks of the constraint matrix
\eqn{\mathbf{A} = \begin{bmatrix} \mathbf{C} & \mathbf{S} \\
                                  \mathbf{M} & \mathbf{Q}
                  \end{bmatrix}}.
If \eqn{\boldsymbol{C}} and/or \eqn{\boldsymbol{M}} are provided, the
matrix \eqn{\boldsymbol{A}} is constructed accordingly. If both are
\code{NULL} and \eqn{\boldsymbol{A}} is not yet defined, an error is
raised.}

\item{b}{numeric vector or \code{NULL}
Right-hand-side vector. Must have as many rows as \eqn{\boldsymbol{A}}.
Required.}

\item{m, p}{integer scalar or \code{NULL}
Dimensions of \eqn{\mathbf{X} \in \mathbb{R}^{m \times p}}, relevant for
allocation problems ('ap').}

\item{i, j}{integer scalar, default = \code{1}
Grouping sizes for row and column-sum constraints in AP problems.}

\item{zero_diagonal}{logical scalar, default = \code{FALSE}
If \code{TRUE}, enforces structural zero diagonals via identity truncation.}

\item{r}{integer scalar, default = \code{1}
Number of refinement iterations for the pseudoinverse-based estimator.
When \eqn{r > 1}, the slack block \eqn{\boldsymbol{Q}} is updated
iteratively to improve feasibility in underdetermined or ill-posed systems.}

\item{Z}{numeric matrix or \code{NULL}
A symmetric idempotent matrix (projector) defining the subspace for
Bott–Duffin pseudoinversion. If \code{NULL}, the identity matrix is used,
reducing to the Moore–Penrose case.}

\item{rcond}{numeric scalar or logical scalar, default = \code{FALSE}
Regularization parameter for the Moore–Penrose and Bott–Duffin inverses,
providing numerically stable inversion and ensuring convergence of singular
values. If \code{TRUE}, an automatic tolerance equal to \code{tolerance} is
applied. If set to a numeric value, it specifies the relative cutoff below
which small singular values are treated as zero.}

\item{tolerance}{numeric scalar or \code{NULL}, default = \code{NULL}
Convergence tolerance for NRMSE change between iterations.}

\item{iteration_limit}{integer scalar or \code{NULL}, default = \code{NULL}
Maximum number of iterations allowed in the refinement loop.}

\item{final}{logical scalar, default = \code{TRUE}
If \code{TRUE}, a convex programming problem is solved to refine
\code{zhat}. The resulting solution \eqn{\boldsymbol{z}} minimizes a
weighted \eqn{\ell_1/\ell_2} norm around \eqn{\widehat{\mathbf{z}}}
subject to \eqn{\mathbf{A}\mathbf{z} = \mathbf{b}}.}

\item{alpha}{numeric scalar, numeric vector, or \code{NULL},
default = \code{NULL}
Regularization parameter:
\itemize{
\item \eqn{\alpha = 0}: Lasso (\eqn{\ell_1} norm)
\item \eqn{\alpha = 1}: Ridge (\eqn{\ell_2} norm)
\item \eqn{0 < \alpha < 1}: Elastic Net.
If a numeric scalar is provided, that value is used after clipping to
\eqn{[0,1]}. If a numeric vector is provided, each candidate is evaluated
via a full solve, and the \eqn{\alpha} with the smallest NRMSE is selected.
If \code{NULL}, \eqn{\alpha} is chosen automatically according to
\deqn{\alpha =
       \min\left(1,\,
       \frac{\mathrm{NRMSE}_{\alpha=0}}
            {\mathrm{NRMSE}_{\alpha=0} +
             \mathrm{NRMSE}_{\alpha=1} +
             \mathrm{tolerance}}\right)}.
}}

\item{cond_tolerance}{numeric scalar or \code{NULL}, default = \code{NULL}
Singular-value cutoff for the custom condition number function.
If \code{NULL}, the implementation uses an internal relative cutoff of
1e-14.}

\item{...}{Optional.
Additional arguments passed to the \pkg{CVXR} solver backend.}
}
\value{
An object of class \code{"clsp"} representing the fitted
Convex Least Squares Programming (CLSP) model.
The object is a named list containing all initialized fields and
solver results.
Class-specific methods such as \code{summary.clsp()},
\code{corr.clsp()}, and \code{ttest.clsp()} can be used to
extract, analyze, and summarize the results.
}
\description{
The Convex Least Squares Programming (CLSP) estimator solves
underdetermined, ill-posed, or structurally constrained least-squares
problems using a modular two-step approach. The first step computes a
pseudoinverse-based estimate, and the second step applies a convex
correction (Lasso, Ridge, or Elastic Net) to ensure numerical stability,
constraint enforcement, and interpretability.
}
\details{
This estimator unifies pseudoinverse-based least squares with convex
programming correction. The pseudoinverse step computes an initial solution
\eqn{\mathbf{z}^{(r)}} iteratively via the Moore–Penrose or Bott–Duffin
inverse. The convex step then refines \eqn{\boldsymbol{z}} by minimizing a
mixed \eqn{\ell_1/\ell_2} norm under equality constraints
\eqn{\mathbf{A}\mathbf{z} = \mathbf{b}}. The method supports allocation
problems (AP), constrained modular least squares (CMLS), and general CLSP
formulations.

To ensure cross-platform reproducibility, all CLSP implementations use a
modified condition number function based on singular values, with a relative
cutoff equal to \eqn{cond\_tolerance\ *\ the\ largest\ singular\ value}.
}
\examples{
\dontrun{
  ## Example: CMLS (RP) estimation with stationary-point constraints

  set.seed(123456789)

  # sample (dataset)
  k  <- 500L                                        # number of observations
  p  <- 6L                                          # number of regressors
  c0 <- 1                                           # sum of coefficients

  D        <- matrix(NA_real_, nrow = k, ncol = p)
  D[, 1]   <- 1.0                                   # constant
  D[, 2:p] <- matrix(rnorm(k * (p - 1)), k, p - 1)

  b_true   <- rnorm(p)
  b_true   <- (b_true / sum(b_true)) * c0           # normalize to sum = c

  e        <- matrix(rnorm(k), ncol = 1)
  y        <- D \%*\% b_true + e

  # build blocks for CLSP (CMLS)
  b <- rbind(
      matrix(c0, ncol = 1),                         # sum of coefficients
      matrix(0,  nrow = k - 2, ncol = 1),
      matrix(0,  nrow = k - 1, ncol = 1),
      matrix(y,  ncol = 1)
  )

  C <- rbind(
      matrix(1, nrow = 1, ncol = p),                # row of ones
      diff(D, differences = 2),                     # 2nd differences
      diff(D, differences = 1)                      # 1st differences
  )

  # diagonal sign-matrix for 2nd differences
  S <- rbind(
      matrix(0, nrow = 1,      ncol = k - 2),
      diag(sign(diff(as.numeric(y), differences = 2))),
      matrix(0, nrow = k - 1,  ncol = k - 2)
  )

  # model
  model <- rclsp::clsp(
      problem = "cmls",
      b       = b,
      C       = C,
      S       = S,
      M       = D,
      r       = 1L,                                 # no refinement
      alpha   = 1.0                                 # MNBLUE solution
  )

  # results
  print("true beta (x_M):")
  print(round(b_true, 4))

  print("beta hat (x_M hat):")
  print(round(model$x, 4))

  print(model)

  # bootstrap t-test
  tt <- rclsp::ttest(
      model,
      sample_size  = 30L,
      seed         = 123456789L,
      distribution = rnorm,
      partial      = TRUE
  )

  print("Bootstrap t-test:")
  print(tt)
}

}
\seealso{
\link[CVXR]{CVXR}
}
