當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。