I need to fit a spline to a set of data and the resulting function is required to be monotonically decreasing and convex. The data I am passing to splinefun are guaranteed to have these properties, but this does not guarantee that the resulting function is convex. Is there any way to fit a spline to a set of data and require that the resulting function is convex?
My other answer on this question showed the monotonic spline and the cobs and scam shape constrained splines. The problem with these shape constrained splines are that they are fairly slow and do not necessarily interpolate all of the datapoints.
I have released a package that implements the Schumaker spline which is monotonic and convex/concave if the data is monotonic and convex/concave. It is fast and interpolates all data points.
For an example:
#install.packages("schumaker")
library(schumaker)
x = seq(1,10)
y = -log(x)
xarray = seq(1,10,0.01)
SchumSpline = schumaker::Schumaker(x,y)
Schum0 = SchumSpline$Spline(xarray)
Schum1 = SchumSpline$DerivativeSpline(xarray)
Schum2 = SchumSpline$SecondDerivativeSpline(xarray)
plot(xarray, Schum0, type = "l", col = 4, ylim = c(-3,1), main = "Schumaker Spline and first two derivatives",
ylab = "Spline and derivatives", xlab = "x")
points(x,y)
lines(xarray, Schum1, col = 2)
lines(xarray, Schum2, col = 3)
abline(h = 0, col = 1)
text(x=rep(8,8,8), y=c(-2, -0.5,+0.2), pos=4, labels=c('Spline', 'First Derivative', 'Second Derivative'))
You can see the second derivative is always positive (This is not true for the normal monotonic spline. See the package's vignette).
Note that the spline will only be globally convex/concave if the data is globally convex/concave. This is unavoidable as this is an interpolating spline.
This spline is faster than the cobs and scam splines. It is slower to create than the monotonic spline but faster to evaluate. Full speed tests can be found in the vignette.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With