# code based on files "Code regarding section 4.2", "Code regarding section 4.3-4.4",
# "Code regarding section 4.5" and "Code regarding section 4.6"
# (copyright 2003, 2004, 2012 A.Azzalini and B.Scarpa)

# call the library splines for fitting splines
library(splines)

# download the data
dataset <- read.table("http://azzalini.stat.unipd.it/Book-DM/yesterday.dat", header = TRUE)
attach(dataset)

### code to reproduce figure 4.5a of Azzalini & Scarpa (2012) ###
# plot the data
xi <- seq(min(x), max(x), length = 4)
plot(x, y.yesterday, pch = 17, col = 2, ylab = "y", cex = 2)
abline(v = xi[2], lty = 3, lwd = 2)
abline(v = xi[3], lty = 3, lwd = 2)

# continuous piecewise linear fit
x0 <- seq(min(x), max(x), length = 200)
xx <- sort(c(x0, xi[2:3]))
m1 <- lm(y.yesterday ~  bs(x, knots = xi[2:3], degree = 1)) # degree 1 = linear
fit1<- predict(m1,  data.frame(x = xx))
lines(xx, fit1, col = 3, lwd = 2)

# continuous piecewise quadratic fit
m2 <- lm(y.yesterday ~  bs(x, knots = xi[2:3], degree = 2)) # degree 2 = quadratic
fit2 <- predict(m2,  data.frame(x = xx))
lines(xx, fit2, col = 4, lwd = 2)

# continuous piecewise cubic fit
m3 <- lm(y.yesterday ~  bs(x, knots = xi[2:3], degree = 3))
fit3 <- predict(m3,  data.frame(x = xx))
lines(xx, fit3, col = 5, lwd = 2)

# use this instead of legend
text(x = c(1.05, 0.85, 0.65), y = rep(0.52, 3), as.character(1:3))

# figure 4.5b
plot(c(0.5, 3), c(0, 2), type = "n", xlab = "x",
     ylab = "max(0,x-1.333)")
abline(v = xi[2], lty = 3)
lines(x0, pmax(0, x0 - xi[2]), col = 1, lwd = 2)

detach(dataset)

# example of thin-plate splines
auto <- read.table("http://azzalini.stat.unipd.it/Book-DM/auto.dat", header = TRUE)
attach(auto)
y <- city.distance
x <- engine.size
xlab <- "Engine size (L)"
ylab <- "Curb weight (kg)"
zlab <- "City distance (km/L)"

# figure 4.6
a075 <- smooth.spline(x, y, spar = 0.75)
a090 <- smooth.spline(x, y, spar = 0.95)
a125 <- smooth.spline(x, y, spar = 1.25)
x0 <- seq(min(x), max(x), length = 250)

par(mfrow = c(1, 1))
plot(x, y, xlab = xlab, ylab = zlab,  cex = 2, pch = 16)
lines(predict(a075, x = x0), col = 2, lty = 1, lwd = 3)
lines(predict(a090, x = x0), col = 3, lty = 1, lwd = 3)
lines(predict(a125, x = x0), col = 4, lty = 1, lwd = 3)
legend('topright', legend = c('l  =  0.0007', 
                              'l  =  0.02',
                              'l  =  2.9'),
       col = c(2, 3, 4), lty = c(1, 1, 1))


# code to plot figure 4.7
library(mgcv)

convex.hull <- function(x, eval.points)
{
  ngrid <- nrow(eval.points)
  hull.points <- x[order(x[, 1], x[, 2]), ]
  dh <- diff(hull.points)
  hull.points <- hull.points[c(TRUE, !((dh[, 1] == 0) & (dh[, 2] == 0))), ]
  hull.points <- hull.points[chull(hull.points), ]
  nh <- nrow(hull.points)
  gstep <- matrix(rep(eval.points[2, ] - eval.points[1, ], nh),
                  ncol = 2, byrow = TRUE)
  hp.start <- matrix(rep(eval.points[1, ], nh), ncol = 2,
                     byrow = TRUE)
  hull.points <- hp.start + gstep * round((hull.points -
                                             hp.start)/gstep)
  hull.points <- hull.points[chull(hull.points), ]
  grid.points <- cbind(rep(eval.points[ , 1], ngrid),
                       rep(eval.points[ , 2], rep(ngrid, ngrid)))
  D <- diff(rbind(hull.points, hull.points[1, ]))
  temp <- D[, 1]
  D[, 1] <- D[, 2]
  D[, 2] <- (-temp)
  C <- as.vector((hull.points * D) %*% rep(1, 2))
  C <- matrix(rep(C, ngrid^2), nrow = ngrid^2, byrow = TRUE)
  D <- t(D)
  wy <- ((grid.points %*% D) >= C)
  wy <- apply(wy, 1, all)
  wy[wy] <- 1
  wy[!wy] <- NA
  wy <- matrix(wy, ncol = ngrid)
  wy
}

m1 <- gam(city.distance ~ s(engine.size, curb.weight, k = 18), data = auto)

x1 <- seq(min(engine.size), max(engine.size), length = 50)
x2 <- seq(min(curb.weight), max(curb.weight), length = 50)
x12 <- data.frame(engine.size = as.vector(outer(x1, rep(1, length(x1)))),
                  curb.weight = as.vector(outer(rep(1, length(x2)), x2)))
m1p <- predict(m1, newdata = x12)

# figure 4.7a
matrice.spline <- matrix(m1p, 50, 50)
w1 <- convex.hull(cbind(engine.size, curb.weight), cbind(x1, x2))
persp(x1, x2, matrice.spline * w1, theta = 120, phi = 20, 
      xlab = "Engine size", ylab = "Curb weight", zlab = "City distance",
      ticktype = "detailed")

detach(package:mgcv, unload = TRUE)

y  <- city.distance
x1 <- engine.size
x2 <- curb.weight

library(gam)

a2 <- gam(city.distance ~ s(engine.size) + s(curb.weight),  data = auto)
pa2 <- preplot(a2)

# figure 4.12a
plot(pa2$"s(engine.size)", se = TRUE, ylim = c(-7, 10), lwd = 2,
     xlab = "Engine size", ylab = "s(Engine size)")

# figure 4.12b
plot(pa2$"s(curb.weight)", se = TRUE, ask = TRUE, ylim = c(-7,10), lwd = 2,
     xlab = "Curb weight", ylab = "s(Curb weight)")


library(sm)

x1 <- seq(min(engine.size), max(engine.size), length = 50)
x2 <- seq(min(curb.weight), max(curb.weight), length = 50)
x12<- data.frame(
  engine.size = as.vector(outer(x1, rep(1, length(x1)))),
  curb.weight = as.vector(outer(rep(1, length(x2)), x2)))
a2p <- predict(a2, x12)
sm.options(ngrid = 50)
h<- c(0.5, 150)

# figure 4.13a
matrice.gam <- matrix(a2p, 50, 50)
w1<-convex.hull(cbind(engine.size, curb.weight), cbind(x1, x2))
persp(x1, x2, matrice.gam * w1, theta = 120, phi = 20, 
      xlab = "Engine size", ylab = "Curb weight", zlab = "City distance",
      ticktype = "detailed")

# figure 4.13b
sm <- sm.regression(cbind(engine.size, curb.weight), city.distance, h = h,
                    options=list(xlab = xlab, ylab = ylab, 
                                 zlab = zlab), display = "none")
matrice.sm <- matrix(sm$estimate, 50, 50)
persp(x1, x2, matrice.sm, theta = 120, phi = 20, 
      xlab = "Engine size", ylab = "Curb weight", zlab = "City distance",
      ticktype = "detailed")


