cm.splinefun {posum} | R Documentation |
Returns an interpolating spline function that has had its
coefficients filtered using Hyman's (1983) algorithm for ensuring
co-monotonicity. The filter is slightly modified to enable the user to
set an upper limit on the gradient of the interpolant. The routine is a
modification of the R base splinefun
routine.
cm.splinefun(x, y = NULL, method = "fmm",gulim=0)
x |
A set of x values |
y |
y values corresponding to the x values. These y values will be interpolated to produce a function of x passing through the x,y points. |
method |
end condition method, can be "natural" , "periodic"
or "fmm" - see splinefun for details |
gulim |
if this is non-zero then it is taken as the upper limit on the gradient of the returned spline function (obviously, this can't be less than the maximum gradient of any line segment joining adjacent points). |
The code is modified from splinefun
, and directly calls
compiled routines spline_coef()
and spline_eval()
from the
R
base package. The method is as follows:
spline_coef()
to get the coefficients of the
interpolating cubic spline through x,y
. Let the returned gradients
w.r.t. x
at x,y
be b
. y
to y-x*gulim
and b
to
b-gulim
.x,y,b
data. Hyman's Algorithm works on the Hermite polynomial representation,
so this is all that's needed. Modified b
values are returned.y,b
values. y
becomes y+x*gulim
and code{b} becomes b+gulim
.x,y,b
values by calling spl.coef.conv
. spline.eval()
with the filtered
coefficients in order to return the evaluated fitted spline.
The y,b
transformation trick is used to turn the monotonicity method
into a gradient limit method.
The function returns a function which will return the filtered interpolant evaluated at each value of its array argument.
The routine does not check that the upper gradient limit is possible given the data to be interpolated: the user must do this!
Simon N. Wood snw@st-and.ac.uk
Hyman (1983) SIAM J. Sci. Stat. Comput. 4(4):645-654
# simple co-monotonic example x<-c(0,0.2,0.4,3,3.5,4,5,6,7.2,8,10) y<-c(0,0.1,0.3,0.6,0.3,0.2,0.1,0.099,0.099,0.094,0.01) xx<-seq(0,10,length=100) normal.spl<-splinefun(x,y) plot(xx,normal.spl(xx),type="l",col=2,main="co-monotonic spline demonstration") cm.spl<-cm.splinefun(x,y) lines(xx,cm.spl(xx),col=3) points(x,y) # gradient limiting example x<-0:9 y<-c(1,0,2,1,4,3,6,5,8,7) normal.spl<-splinefun(x,y) xx<-seq(0,9,length=100) plot(xx,normal.spl(xx),type="l",col=2,main="gradient limited spline demonstration") cm.spl<-cm.splinefun(x,y,gulim=3) lines(xx,cm.spl(xx),col=3) points(x,y)