Skip to Content

cubic spline interpolation in R [closed]

I am trying an implementation of a cubic spline in R. I have already used the spline, smooth.spline and smooth.Pspline functions that are available in the R libraries but I am not that happy with the results so I want to convince myself about the consistency of the results by a "homemade" spline function. I have already computed the coefficients for the 3rd degree polynomials, but I am not sure how to plot the results..they seem random points. You can find the source code below. Any help would be appreciated.

x = c(35,36,39,42,45,48)
y = c(2.87671519825595, 4.04868309245341,   3.95202175000174,   
  3.87683188946186, 4.07739945984612,   2.16064840967985)
 
 
n = length(x)
 
#determine width of intervals
h=0
for (i in 1:(n-1)){
   h[i] = (x[i+1] - x[i])
}
 
A = 0
B = 0
C = 0
D = 0
#determine the matrix influence coefficients for the natural spline
for (i in 2:(n-1)){
  j = i-1
  D[j] = 2*(h[i-1] + h[i])
  A[j] = h[i]
  B[j] = h[i-1] 
 
}
 
#determine the constant matrix C
for (i in 2:(n-1)){
  j = i-1
  C[j] = 6*((y[i+1] - y[i]) / h[i] - (y[i] - y[i-1]) / h[i-1])
}
 
#maximum TDMA length
ntdma = n - 2
 
#tridiagonal matrix algorithm
 
#upper triangularization
R = 0
for (i in 2:ntdma){
  R = B[i]/D[i-1]
  D[i] = D[i] - R * A[i-1]
  C[i] = C[i] - R * C[i-1] 
}
 
#set the last C
C[ntdma] = C[ntdma] / D[ntdma]
 
#back substitute
for (i in (ntdma-1):1){
  C[i] = (C[i] - A[i] * C[i+1]) / D[i]
}
 
#end of tdma
 
#switch from C to S
S = 0
for (i in 2:(n-1)){
  j = i - 1
  S[i] = C[j]
}
#end conditions
S[1] <- 0 -> S[n]
 
#Calculate cubic ai,bi,ci and di from S and h
for (i in 1:(n-1)){
 A[i] = (S[i+ 1] - S[i]) / (6 * h[i])
 B[i] = S[i] / 2
 C[i] = (y[i+1] - y[i]) / h[i] - (2 * h[i] * S[i] + h[i] * S[i + 1]) / 6
 D[i] = y[i]
}
 
 
#control points
xx = c(x[2],x[4])
yy = 0
#spline evaluation
for (j in 1:length(xx)){
  for (i in 1:n){
    if (xx[j]<=x[i]){
      break
    }
    yy[i] = A[i]*(xx[j] - x[i])^3 + B[i]*(xx[j] - x[i])^2 + C[i]*(xx[j] - x[i]) + D[i]
 
 }
points(x,yy ,col="blue")
}

Thank you