Skip to contents

Fit a continuous response with a piecewise-quadratic curve and an L1 penalty on third divided differences. Dense and banded native C++ solvers share the order-2 geometry of fit.logistic.trend.filtering.

Usage

fit.gaussian.trend.filtering(
  x,
  y,
  lambda,
  weights = NULL,
  covariates = NULL,
  offset = NULL,
  nuisance.ridge = 0,
  curve.ridge = 0,
  lambda.selection = c("fixed", "cv"),
  foldid = NULL,
  control = list(),
  warn = TRUE,
  backend = c("auto", "dense", "banded"),
  cv.penalty.scale = c("training_mass", "none")
)

Arguments

x

Finite numeric predictor, with at least four distinct values.

y

Finite numeric continuous response, with one value per observation. Constant responses are supported.

lambda

Nonnegative penalties, or Inf for the quadratic limit. Required explicitly: no data-dependent default penalty is assumed.

weights

Positive observation weights, default one.

covariates

Optional finite numeric matrix of additional predictors, without an intercept. Columns are centered and scaled on training data.

offset

Optional finite vector added to the linear predictor.

nuisance.ridge, curve.ridge

Nonnegative explicit ridge penalties, default zero. See Details for their precise scaling.

lambda.selection

"fixed" returns the supplied penalty path; "cv" selects minimum held-out weighted mean squared error (MSE).

foldid

Integer fold labels, required for lambda.selection="cv". Supply the same label for observations that must be held out together.

control

Named list overriding tolerance=1e-9, gap.tolerance=1e-10, max.iterations=1000L, or max.workspace.bytes=1024^3. Tolerances apply to mean weighted loss.

warn

Logical; warn when a path fit fails convergence checks.

backend

Native solver: "auto" uses "banded" above 256 distinct locations or when the dense workspace estimate exceeds its limit, and "dense" otherwise. The banded backend uses compact working sets and checks every knot; it does not thin the predictor locations.

cv.penalty.scale

"training_mass" (default) multiplies each fold's lambda and ridge penalties by its training/full weight-sum ratio. This preserves their coefficients relative to mean loss. "none" retains the earlier same-numerical-penalty convention. Fixed-path fits are unchanged.

Value

A gaussian.trend.filtering.fit containing order=2L, the original data, penalty path, fits, convergence diagnostics, training design, and, when requested, cv.table with MSE and eligibility, fold-level loss sums and status, and selected.index. A fixed path has no selected index. cv.penalty.scale, cv.fold.lambda, cv.fold.penalty.factors, and cv.fold.ridge record the actual convention and training penalties. Standard prediction returns NA for unconverged candidates.

Details

With training predictor locations normalized to [0,1], minimize $$\frac{1}{2}\sum_i w_i(y_i-\eta_i)^2 +\lambda\|D^{(3)}f\|_1 +\frac{r_z}{2}\|\gamma\|^2 +\frac{r_f}{2\sum_i w_i}\sum_i w_i(f_i-\bar f_w)^2.$$ Here eta is the curve plus standardized covariates and offset. The intercept is unpenalized. Lambda is on the summed-loss scale; the default ridge penalties are zero. lambda=Inf restricts the curve to a global quadratic, not a constant. At lambda=0 with no covariates, offsets or ridge, predictions at distinct training locations are their weighted response means. Exact ties retain their individual loss contributions. Order is fixed at 2; no order-selection step is performed.

Gaussian refers to squared-error fitting. Fitting and CV do not estimate a noise variance, supply confidence intervals, or assume normality for the permutation assessment. Additional covariates and offsets are supported for fitting; assess.gaussian.trend.filtering supports only independent, unit-weight observations without adjustment.

Every CV split recomputes its training-only predictor range, knots and transformations. The default cv.penalty.scale="training_mass" scales lambda and ridge penalties by the training/full weight-sum ratio; "none" retains the earlier raw-penalty convention. This holds the mean-loss coefficients constant, not a common raw-coordinate operator across splits. Selection requires convergence on the full data and all folds. Equal CV scores select the first supplied lambda. Predictions outside the training range hold the curve at the nearest boundary; covariates and offsets continue to contribute. The banded backend scans all knots without thinning locations. Both solvers require finite arithmetic, stationarity, dual feasibility and L1 complementarity checks; failed fits remain explicit. Tolerances apply to mean weighted loss.

References

Wang, Smola and Tibshirani (2014). The Falling Factorial Basis and Its Statistical Applications. https://arxiv.org/abs/1405.0558

Examples

x <- seq(0, 1, length.out = 40)
y <- sin(2*pi*x) + 0.1*cos(seq_along(x))
fit <- fit.gaussian.trend.filtering(x, y, lambda = c(Inf, 0.01),
    backend = "banded")
predict(fit, c(0.25, 0.75), lambda.index = 2)
#> [1]  0.9314017 -0.9315855
#> attr(,"outside.range")
#> [1] FALSE FALSE
#> attr(,"lambda")
#> [1] 0.01