% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/integrate.R
\name{integrate.lgspline}
\alias{integrate.lgspline}
\title{Definite Integral of a Fitted lgspline}
\usage{
\method{integrate}{lgspline}(
  f,
  lower,
  upper,
  vars = NULL,
  initial_values = NULL,
  B_predict = NULL,
  link_scale = FALSE,
  n_quad = 50L,
  ...
)
}
\arguments{
\item{f}{A fitted \code{lgspline} object.}

\item{lower}{Numeric vector of lower bounds, one per integration variable.
Scalar values are recycled.}

\item{upper}{Numeric vector of upper bounds, one per integration variable.
Scalar values are recycled.}

\item{vars}{Default: NULL.  Character or integer vector identifying which
predictor(s) to integrate over.  When NULL all numeric predictors are
integrated simultaneously.}

\item{initial_values}{Default: NULL.  Numeric vector of length \eqn{q}
supplying fixed values for predictors not among the integration
variables.  When NULL, non-integration predictors are held at the
midpoint of their training range.}

\item{B_predict}{Default: NULL.  Optional list of coefficient vectors,
one per partition.  When NULL the fitted coefficients are used.}

\item{link_scale}{Default: FALSE.  Logical; when TRUE the integral is
computed on the link (linear predictor) scale \eqn{\eta} rather than
the response scale \eqn{\mu}.}

\item{n_quad}{Default: 50.  Number of Gauss--Legendre nodes per
integration dimension.}

\item{\ldots}{Additional arguments (currently unused; present for S3
method compatibility).}
}
\value{
A numeric scalar: the estimated definite integral.
}
\description{
Given a fitted \code{lgspline} object, computes the definite integral of
the fitted surface over a rectangular domain using Gauss--Legendre
quadrature on \code{predict()}.
}
\section{Method}{

The integration domain is discretised into a tensor-product grid of
Gauss--Legendre quadrature nodes.  Predicted values at each node come
from the model's \code{predict()} method, which correctly handles
partition assignment and piecewise polynomial evaluation.  The integral
is the weighted sum
\deqn{\int_{a_1}^{b_1} \cdots \int_{a_d}^{b_d}
      \hat{f}(\mathbf{t})\,\mathrm{d}t_1 \cdots \mathrm{d}t_d
      \;\approx\;
      \sum_{i=1}^{M} w_i\,\hat{f}(\mathbf{t}_i)}
where \eqn{M = n_{\mathrm{quad}}^d} and each weight incorporates the
Jacobian \eqn{(b_j - a_j)/2} for the affine map from \eqn{[-1, 1]} to
\eqn{[a_j, b_j]}.  Nodes and weights on \eqn{[-1, 1]} are computed via
the Golub--Welsch algorithm (eigenvalues of the symmetric tridiagonal
Jacobi matrix).

For smooth polynomials, 30--50 nodes per dimension is typically
sufficient; highly partitioned models (large \eqn{K}) may benefit from
more.  Total evaluation points scale as \eqn{n_{\mathrm{quad}}^d}, so
problems with \eqn{d \ge 4} may require reducing \code{n_quad}.
}

\section{Integration scale}{

By default (\code{link_scale = FALSE}), integration is on the response
scale \eqn{\mu = g^{-1}(\eta)}.  Setting \code{link_scale = TRUE}
integrates the linear predictor \eqn{\eta = \mathbf{x}^{\top}\boldsymbol{\beta}}
directly, which is useful when the quantity of interest is the area
under the link-transformed surface rather than the response.  For the
identity link the two coincide.
}

\examples{

## 1-D: integral of fitted sin(t) over [-pi, pi] should be near 0
set.seed(1234)
t <- seq(-pi, pi, length.out = 1000)
y <- sin(t) + rnorm(length(t), 0, 0.01)
fit <- lgspline(t, y, K = 4, opt = FALSE)
integrate(fit, lower = -pi, upper = pi)

## Base R integrate still works as expected
integrate(sin, lower = -pi, upper = pi)

## 2-D: volume under fitted volcano surface
data(volcano)
vlong <- cbind(
  rep(seq_len(nrow(volcano)), ncol(volcano)),
  rep(seq_len(ncol(volcano)), each = nrow(volcano)),
  as.vector(volcano)
)
colnames(vlong) <- c("Length", "Width", "Height")
fit_v <- lgspline(vlong[, 1:2], vlong[, 3], K = 18,
                  include_quadratic_interactions = TRUE, opt = FALSE)
integrate(fit_v, lower = c(1, 1), upper = c(87, 61))

}
