当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


R splinefun 插值样条曲线


R语言 splinefun 位于 stats 包(package)。

说明

对给定数据点执行三次(或埃尔米特)样条插值,返回通过插值获得的点列表或执行插值的函数。

用法

splinefun(x, y = NULL,
          method = c("fmm", "periodic", "natural", "hyman",
                     "monoH.FC", "clamped", "canonical", "Catmull-Rom"),
          ties = mean, vals)

spline(x, y = NULL, n = 3*length(x), method = "fmm",
       xmin = min(x), xmax = max(x), xout, ties = mean)

splinefunH(x, y, m)

参数

x, y

给出要插值点的坐标的向量。或者,可以指定单个绘图结构:请参阅xy.coords

y 必须针对 method = "hyman" 增加或减少。

m

(对于 splinefunH() ):点 处的斜率向量 ;这些共同决定了 Hermite “spline”,它是分段三次的,(通常仅)一次可连续微分。

method

指定要使用的样条曲线的类型。可能的值为 "fmm""natural""periodic""hyman" ,并且仅适用于 splinefun() 基于埃尔米特样条的 "monoH.FC""clamped""canonical""Catmull-Rom" .可以缩写。

n

如果 xout 未指定,则在跨越区间 [ xminxmax ] 的 n 等距点处进行插值。

xmin, xmax

插值间隔的左侧和右侧端点(当未指定xout 时)。

xout

一组可选值,指定插值发生的位置。

ties

处理绑定的 x 值。字符串 "ordered" 或函数(或函数的名称)采用单个向量参数并返回单个数字或长度为 2 的 list,请参阅 approx 及其“详细信息”部分,以及下面的例子。

vals

对于方法 "clamped" ,两端的斜率 x[1]x[length(x)] ;对于"canonical" 的因子。

细节

输入可能包含已删除的缺失值,因此至少需要一对完整的(x, y)。如果是 method = "fmm" ,则使用的样条是 Forsythe、Malcolm 和 Moler 的样条(通过数据每一端的四个点拟合精确的三次,这用于确定结束条件)。当 method = "natural" 时使用自然样条线,当 method = "periodic" 时使用周期样条线。

方法"monoH.FC" 根据 Fritsch 和 Carlson 的方法计算单调 Hermite 样条。它通过确定斜率来实现这一点,使得由 确定的 Hermite 样条线 (splinefunH() ) 是单调的(增加或减少)当且仅当数据是单调的。

方法 "hyman" 使用适合严格单调输入的 method = "fmm" 的海曼滤波来计算单调三次样条。

这些插值样条还可用于外推,即在 x 范围之外的点进行预测。外推法对于 method = "fmm" 没有什么意义;对于自然样条线,使用最近数据点处的插值曲线的斜率是线性的。

请注意,Hermite 插值样条(通过 splinefunH() )是比其他函数更通用的一类函数。它们具有更多具有任意斜率的自由度,例如,自然插值样条线 ( method = "natural" ) 是特殊情况,其中斜率是除以差值。

spline 返回一个包含组件 xy 的列表,它们给出了发生插值的坐标和插值值。

splinefun 返回带有形式参数 xderiv 的函数,后者默认为零。此函数可用于计算点 x 处的插值三次样条 ( deriv = 0) 或其导数 ( deriv = 1, 2, 3),其中样条函数对最初指定的数据点进行插值。它使用创建时存储在其环境中的数据,其详细信息可能会发生变化。

警告

返回的值splinefun包含对当前版本中代码的引用R:它不打算保存并加载到不同的R会议。这样比较安全R>= 3.0.0。

例子

require(graphics)

op <- par(mfrow = c(2,1), mgp = c(2,.8,0), mar = 0.1+c(3,3,3,1))
n <- 9
x <- 1:n
y <- rnorm(n)
plot(x, y, main = paste("spline[fun](.) through", n, "points"))
lines(spline(x, y))
lines(spline(x, y, n = 201), col = 2)

y <- (x-6)^2
plot(x, y, main = "spline(.) -- 3 methods")
lines(spline(x, y, n = 201), col = 2)
lines(spline(x, y, n = 201, method = "natural"), col = 3)
lines(spline(x, y, n = 201, method = "periodic"), col = 4)
legend(6, 25, c("fmm","natural","periodic"), col = 2:4, lty = 1)

y <- sin((x-0.5)*pi)
f <- splinefun(x, y)
ls(envir = environment(f))
splinecoef <- get("z", envir = environment(f))
curve(f(x), 1, 10, col = "green", lwd = 1.5)
points(splinecoef, col = "purple", cex = 2)
curve(f(x, deriv = 1), 1, 10, col = 2, lwd = 1.5)
curve(f(x, deriv = 2), 1, 10, col = 2, lwd = 1.5, n = 401)
curve(f(x, deriv = 3), 1, 10, col = 2, lwd = 1.5, n = 401)
par(op)

fTrue <- function(x) exp(-3*x) * cos(4*pi*x)
x <- (0:20)/20
y <- fTrue(x)
f1  <- splinefun(x, y)# "fmm"
fn  <- splinefun(x, y, "natural")
f3  <- splinefun(x, y, "clamped", vals=c(-2, 1))
fCR <- splinefun(x, y, "Catmull-Rom")
f5  <- splinefun(x, y, "canonical", vals = 0.8)
x. <- seq(-1, 21, length.out = 1001)/20
matplot(x., cbind(f1(x.), fn(x.), f3(x.), fCR(x.), f5(x.)), type="l"); points(x,y)
ctrue <- adjustcolor("tomato", 1/4)
lines(x., fTrue(x.), col=ctrue, lwd=5)
legend("topright", col=c(palette()[1:5], ctrue), lty=1:5, lwd=c(1,1,1,1,1, 5), bty="n",
       c("fmm", "natural", "clamped(-2,1)", "Catmull-Rom","canonical(0.8)", "true f()"))

## Derivatives :
curve(f1 (x, deriv = 1), n = 1001); abline(h = 0, lty=3)
curve(fn (x, deriv = 1), add=TRUE, col=adjustcolor(2, 1/2), lwd=2.5, n = 1001)
curve(f3 (x, deriv = 1), add=TRUE, col=adjustcolor(3, 1/2), lwd=2.5, n = 1001)
curve(fCR(x, deriv = 1), add=TRUE, col=adjustcolor(4, 1/2), lwd=2.5, n = 1001)
curve(f5 (x, deriv = 1), add=TRUE, col=adjustcolor(5, 1/2), lwd=1.5, n = 1001)
legend("topright", col=c("black", adjustcolor(2:5, 1/2)), bty="n", lwd=c(1, rep(2.5,4)),
       c("fmm", "natural", "clamped(-2,1)", "Catmull-Rom","canonical(0.8)"))


## 2nd derivatives:  piecewise linear, only first three are continuous
curve(f1 (x, deriv = 2), n = 1001); abline(h = 0, lty=3)
curve(fn (x, deriv = 2), add=TRUE, col=adjustcolor(2, 1/2), lwd=2.5, n = 1001)
curve(f3 (x, deriv = 2), add=TRUE, col=adjustcolor(3, 1/2), lwd=2.5, n = 1001)
curve(fCR(x, deriv = 2), add=TRUE, col=adjustcolor(4, 1/2), lwd=2.5, n = 1001)
legend("topright", col=c("black", adjustcolor(2:5, 1/2)), bty="n", lwd=c(1, rep(2.5,4)),
       c("fmm", "natural", "clamped(-2,1)", "Catmull-Rom"))


## Manual spline evaluation --- demo the coefficients :
.x <- splinecoef$x
u <- seq(3, 6, by = 0.25)
(ii <- findInterval(u, .x))
dx <- u - .x[ii]
f.u <- with(splinecoef,
            y[ii] + dx*(b[ii] + dx*(c[ii] + dx* d[ii])))
stopifnot(all.equal(f(u), f.u))

## An example with ties (non-unique  x values):
set.seed(1); x <- round(rnorm(30), 1); y <- sin(pi * x) + rnorm(30)/10
plot(x, y, main = "spline(x,y)  when x has ties")
lines(spline(x, y, n = 201), col = 2)
## visualizes the non-unique ones:
tx <- table(x); mx <- as.numeric(names(tx[tx > 1]))
ry <- matrix(unlist(tapply(y, match(x, mx), range, simplify = FALSE)),
             ncol = 2, byrow = TRUE)
segments(mx, ry[, 1], mx, ry[, 2], col = "blue", lwd = 2)

## Another example with sorted x, but ties:
set.seed(8); x <- sort(round(rnorm(30), 1)); y <- round(sin(pi * x) + rnorm(30)/10, 3)
summary(diff(x) == 0) # -> 7 duplicated x-values
str(spline(x, y, n = 201, ties="ordered")) # all '$y' entries are NaN
## The default (ties=mean) is ok, but most efficient to use instead is
sxyo <- spline(x, y, n = 201, ties= list("ordered", mean))
sapply(sxyo, summary)# all fine now
plot(x, y, main = "spline(x,y, ties=list(\"ordered\", mean))  for when x has ties")
lines(sxyo, col="blue")

## An example of monotone interpolation
n <- 20
set.seed(11)
x. <- sort(runif(n)) ; y. <- cumsum(abs(rnorm(n)))
plot(x., y.)
curve(splinefun(x., y.)(x), add = TRUE, col = 2, n = 1001)
curve(splinefun(x., y., method = "monoH.FC")(x), add = TRUE, col = 3, n = 1001)
curve(splinefun(x., y., method = "hyman")   (x), add = TRUE, col = 4, n = 1001)
legend("topleft",
       paste0("splinefun( \"", c("fmm", "monoH.FC", "hyman"), "\" )"),
       col = 2:4, lty = 1, bty = "n")

## and one from Fritsch and Carlson (1980), Dougherty et al (1989)
x. <- c(7.09, 8.09, 8.19, 8.7, 9.2, 10, 12, 15, 20)
f <- c(0, 2.76429e-5, 4.37498e-2, 0.169183, 0.469428, 0.943740,
       0.998636, 0.999919, 0.999994)
s0 <- splinefun(x., f)
sn <- splinefun(x., f, method = "natural")
s1 <- splinefun(x., f, method = "monoH.FC")
s2 <- splinefun(x., f, method = "hyman")
plot(x., f, ylim = c(-0.2, 1.2))
curve(s0(x), add = TRUE, col = 2, n = 1001) -> m0
curve(sn(x), add = TRUE, col = 3, n = 1001)
curve(s1(x), add = TRUE, col = 4, n = 1001)
curve(s2(x), add = TRUE, col = 5, n = 1001)
legend("right",
       paste0("splinefun( \"", c("fmm", "natural", "monoH.FC", "hyman"), "\" )"),
       col = 2:5, lty = 1, bty = "n")

## "fmm" has continuous (piecewise linear) 2nd derivative :
curve(s0(x, deriv=2), xlim = range(x.), n=1000); abline(h=0, lty=3)
## but the monotone (hermite) splines do *not*:
cl <- adjustcolor(1:3, 1/2)
x.. <- sort(outer(x., (-1:1)/1000, "+"))
matplot(x.., cbind(s0(x.., 2), s1(x.., 2), s2(x.., 2)),
        type = "o", pch=1:3, col = cl, lty=1, lwd=2, cex=3/4)
legend("topright",
       paste0("splinefun( \"", c("fmm", "monoH.FC", "hyman"), "\" )"),
       pch=1:3, col = cl, lty=1, lwd=2, pt.cex=3/4, bty = "n")

## they seem identical, but are not quite:
xx <- m0$x
plot(xx, s1(xx) - s2(xx), type = "l",  col = 2, lwd = 2,
     main = "Difference   monoH.FC - hyman"); abline(h = 0, lty = 3)

x <- xx[xx < 10.2] ## full range: x <- xx .. does not show enough
ccol <- adjustcolor(2:4, 0.8)
matplot(x, cbind(s0(x, deriv = 2), s1(x, deriv = 2), s2(x, deriv = 2))^2,
        lwd = 2, col = ccol, type = "l", ylab = quote({{f*second}(x)}^2),
        main = expression({{f*second}(x)}^2 ~" for the three 'splines'"))
legend("topright",
       paste0("splinefun( \"", c("fmm", "monoH.FC", "hyman"), "\" )"),
       lwd = 2, col  =  ccol, lty = 1:3, bty = "n")
## --> "hyman" has slightly smaller  Integral f''(x)^2 dx  than "FC",
## here, and both are 'much worse' than the regular fmm spline.

作者

R Core Team.

Simon Wood for the original code for Hyman filtering.

参考

Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988). The New S Language. Wadsworth & Brooks/Cole.

Dougherty, R. L., Edelman, A. and Hyman, J. M. (1989) Positivity-, monotonicity-, or convexity-preserving cubic and quintic Hermite interpolation. Mathematics of Computation, 52, 471-494. doi:10.1090/S0025-5718-1989-0962209-1.

Forsythe, G. E., Malcolm, M. A. and Moler, C. B. (1977). Computer Methods for Mathematical Computations. Wiley.

Fritsch, F. N. and Carlson, R. E. (1980). Monotone piecewise cubic interpolation. SIAM Journal on Numerical Analysis, 17, 238-246. doi:10.1137/0717021.

Hyman, J. M. (1983). Accurate monotonicity preserving cubic interpolation. SIAM Journal on Scientific and Statistical Computing, 4, 645-654. doi:10.1137/0904045.

https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation on boundary conditions in addition to the natural ones;

https://en.wikipedia.org/wiki/Cubic_Hermite_spline for background on splinefunH() related methods "clamped", "canonical" and "Catmull-Rom".

也可以看看

approxapproxfun 用于常数和线性插值。

splines,特别是用于插值样条的interpSplineperiodicSpline。该包还生成可用于回归样条线的样条线基。

smooth.spline 用于平滑样条线。

相关用法


注:本文由纯净天空筛选整理自R-devel大神的英文原创作品 Interpolating Splines。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。