\name{smooth.construct.ps.smooth.spec}
\alias{smooth.construct.ps.smooth.spec}
\alias{smooth.construct.cp.smooth.spec}
\alias{p.spline}
\alias{cyclic.p.spline}
%- Also NEED an `\alias' for EACH other topic documented here.
\title{P-splines in GAMs}

\description{\code{\link{gam}} can use univariate P-splines as proposed by Eilers and Marx (1996), 
specified via terms like \code{s(x,bs="ps")}. These terms use B-spline bases 
penalized by discrete penalties applied directly to 
the basis coefficients. Cyclic P-splines are specified by model terms like \code{s(x,bs="cp",...)}. 
These bases can be used in tensor product smooths (see \code{\link{te}}).

The advantage of P-splines is the flexible way that penalty and basis order can be mixed (but see also \code{\link{d.spline}}). This often provides a useful way of `taming' an otherwise poorly behave smooth. However, in regular use, splines with derivative based penalties (e.g. \code{"tp"} or \code{"cr"} bases) tend to result in slightly better MSE performance, presumably because the good approximation theoretic properties of splines are rather closely connected to the use of derivative penalties. 

}

\usage{
\method{smooth.construct}{ps.smooth.spec}(object, data, knots)
\method{smooth.construct}{cp.smooth.spec}(object, data, knots)
}

\arguments{ 
\item{object}{a smooth specification object, usually generated by a term \code{s(x,bs="ps",...)} or 
      \code{s(x,bs="cp",...)}}

\item{data}{a list containing just the data (including any \code{by} variable) required by this term, 
            with names corresponding to \code{object$term} (and \code{object$by}). The \code{by} variable 
            is the last element.} 

\item{knots}{a list containing any knots supplied for basis setup --- in same order and with same names as \code{data}. 
             Can be \code{NULL}. See details for further information.}

}

\value{ An object of class \code{"pspline.smooth"} or \code{"cp.smooth"}. See \code{\link{smooth.construct}}, 
for the elements that this object will contain.
}

\details{A  smooth term of the form \code{s(x,bs="ps",m=c(2,3))} specifies a 2nd order P-spline basis (cubic spline), 
with a third order difference penalty (0th order is a ridge penalty) on the coefficients. If \code{m} is a single number then it is taken as the basis order and penalty order. The default is the `cubic spline like' \code{m=c(2,2)}.

The default basis dimension, \code{k}, is the larger of 10 and \code{m[1]+1} for a \code{"ps"} terms and the larger of 10 and \code{m[1]} for a \code{"cp"} term. \code{m[1]+1} and \code{m[1]} are the lower limits on basis dimension for the two types. 

If knots are supplied, then the number of knots should be one more than the basis dimension 
(i.e. \code{k+1}) for a \code{"cp"}smooth. For the \code{"ps"} basis the number of supplied knots should be \code{k + m[1] + 2}, and the range of the middle \code{k-m[1]} knots should include all the covariate values. See example.

Alternatively, for both types of smooth, 2 knots can be supplied, denoting the 
lower and upper limits between which the spline can be evaluated (Don't make this range too wide, however, or you 
can end up with no information about some basis coefficients, because the corresponding basis functions have a 
span that includes no data!). Note that P-splines don't make much sense with uneven knot spacing.

Linear extrapolation is used for prediction that requires extrapolation 
(i.e. prediction outside the range of the interior \code{k-m[1]} knots). Such extrapolation is not
allowed in basis construction, but is when predicting.

For the \code{"ps"} basis it is possible to set flags in the smooth specification object, requesting setup
according to the SCOP-spline monotonic smoother construction of Pya and Wood (2015). As yet this is not 
supported by any modelling functions in \code{mgcv} (see package \code{scam}). Similarly it is possible to set a 
\code{deriv} flag in a smooth specification or smooth object, so that a model or prediction matrix produces the
requested derivative of the spline, rather than evaluating it. See examples below. 

}

\references{
Eilers, P.H.C. and B.D. Marx (1996) Flexible Smoothing with B-splines and Penalties. 
Statistical Science, 11(2):89-121

Pya, N., and Wood, S.N. (2015). Shape constrained additive models. Statistics and Computing, 25(3), 543-559.
}

\author{ Simon N. Wood \email{simon.wood@r-project.org}}

\seealso{\code{\link{cSplineDes}}, \code{\link{adaptive.smooth}}, \code{\link{d.spline}}}

\examples{
## see ?gam
## cyclic example ...
  require(mgcv)
  set.seed(6)
  x <- sort(runif(200)*10)
  z <- runif(200)
  f <- sin(x*2*pi/10)+.5
  y <- rpois(exp(f),exp(f)) 

## finished simulating data, now fit model...
  b <- gam(y ~ s(x,bs="cp") + s(z,bs="ps"),family=poisson)

## example with supplied knot ranges for x and z (can do just one)
  b <- gam(y ~ s(x,bs="cp") + s(z,bs="ps"),family=poisson,
           knots=list(x=c(0,10),z=c(0,1))) 

## example with supplied knots...
  bk <- gam(y ~ s(x,bs="cp",k=12) + s(z,bs="ps",k=13),family=poisson,
                      knots=list(x=seq(0,10,length=13),z=(-3):13/10))

## plot results...
  par(mfrow=c(2,2))
  plot(b,select=1,shade=TRUE);lines(x,f-mean(f),col=2)
  plot(b,select=2,shade=TRUE);lines(z,0*z,col=2)
  plot(bk,select=1,shade=TRUE);lines(x,f-mean(f),col=2)
  plot(bk,select=2,shade=TRUE);lines(z,0*z,col=2)
  
## Example using montonic constraints via the SCOP-spline
## construction, and of computng derivatives...
  x <- seq(0,1,length=100); dat <- data.frame(x)
  sspec <- s(x,bs="ps")
  sspec$mono <- 1
  sm <- smoothCon(sspec,dat)[[1]]
  sm$deriv <- 1
  Xd <- PredictMat(sm,dat)
## generate random coeffients in the unconstrainted 
## parameterization...
  b <- runif(10)*3-2.5
## exponentiate those parameters indicated by sm$g.index 
## to obtain coefficients meeting the constraints...
  b[sm$g.index] <- exp(b[sm$g.index]) 
## plot monotonic spline and its derivative
  par(mfrow=c(2,2))
  plot(x,sm$X\%*\%b,type="l",ylab="f(x)")
  plot(x,Xd\%*\%b,type="l",ylab="f'(x)")
## repeat for decrease...
  sspec$mono <- -1
  sm1 <- smoothCon(sspec,dat)[[1]]
  sm1$deriv <- 1
  Xd1 <- PredictMat(sm1,dat)
  plot(x,sm1$X\%*\%b,type="l",ylab="f(x)")
  plot(x,Xd1\%*\%b,type="l",ylab="f'(x)")

## Now with sum to zero constraints as well...
  sspec$mono <- 1
  sm <- smoothCon(sspec,dat,absorb.cons=TRUE)[[1]]
  sm$deriv <- 1
  Xd <- PredictMat(sm,dat)
  b <- b[-1] ## dropping first param
  plot(x,sm$X\%*\%b,type="l",ylab="f(x)")
  plot(x,Xd\%*\%b,type="l",ylab="f'(x)")
  
  sspec$mono <- -1
  sm1 <- smoothCon(sspec,dat,absorb.cons=TRUE)[[1]]
  sm1$deriv <- 1
  Xd1 <- PredictMat(sm1,dat)
  plot(x,sm1$X\%*\%b,type="l",ylab="f(x)")
  plot(x,Xd1\%*\%b,type="l",ylab="f'(x)")
  
}
\keyword{models} \keyword{regression}%-- one or more ..


