My understanding is that one of the attractive properties of the B-spline basis is that the individual basis functions have local support, i.e. it will be >0 on the interval between $d+2$ adjacent knots (letting $d$ be the degree of the spline basis), but zero everywhere else. However, the p-spines used in mgcv do not appear to have this property.

gamfit <- gam(accel ~ s(times, bs="ps"), data=mcycle)
mc_ord <- mcycle[order(mcycle$times), ]
X <- predict(gamfit, mc_ord, type='lpmatrix')
matplot(y=X, x=mc_ord$times, type='l')

After extracting the spline basis projection using predict(gamfit, mc_ord, type='lpmatrix') and plotting the columns against the original unprojected variable, I'm seeing that the splines used in mgcv (using bs="ps") do not appear to be non-negative.

Simon Wood is a super smart dude, so I assume I am misinformed/confused/ignorant somehow. Can someone help me become less misinformed/confused/ignorant?

My main questions:

  1. After some googling, I'm finding the many different types of splines confusing. Is there a standard nomenclature? What do we call this type of spline / B-spline variant?
  2. What is the advantage of using this type of spline basis function versus one that is non-zero?
  3. Is there a way to require mgcv to use splines with local support?
  • $\begingroup$ Can anyone help me with this? I'm not finding much information out there (or perhaps just having trouble figuring out the right search terms) $\endgroup$ Oct 13, 2020 at 3:06

1 Answer 1


It's because of the sum to zero constraints. If you only need single smooths in your model there are a couple of options...

## set up p-spline smoother without constraint
sm <- smoothCon(s(times,bs="ps",k=20),data=mcycle)[[1]]
X <- sm$X ## no constraint => compact support
S <- sm$S[[1]]
accel <- mcycle$accel
m <- gam(accel~X-1,paraPen=list(X=list(S)))

## or fool gam into not using a constraint... 
n <- nrow(mcycle)
## dum is basically a constant, but just variable enough for gam to 
## not impose a constraint... 
dum <- rep(1,n) + (runif(n)-.5) * 1e-8
m <- gam(accel~s(times,bs="ps",k=20,by=dum)-1,data=mcycle)

If you need multiple smooths then you can just clone the p-spline smooth constructors and set constraints that maintain compact support - the problem is that they tend to lead to very wide CI's as you get confounding via the intercept...


  • $\begingroup$ Thank you! I ended up creating the splines with compact support "by hand," but I'm intrigued by the solution using the dummy constraint variable! $\endgroup$ Oct 14, 2020 at 17:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.