我打算将一个夹紧的b样条拟合到R中的一组控制点,但很难理解bs中knots
参数的使用
path <- data.frame(
x = c(3, 3.5, 4.6875, 9.625, 5.5625, 19.62109375, 33.6796875, 40.546875, 36.59375, 34.5, 33.5, 33),
y = c(0, 1, 4, 5, 6, 8, 7, 6, 5, 2, 1, 0)
)
我根据路径上的距离独立地拟合x和y:
path$distance <- c(0, cumsum(sqrt(diff(path[,1])^2 + diff(path[,2])^2)))
path$distance
## [1] 0.000000 1.118034 4.344511 9.382259 13.566026 27.766169 41.860284 48.799899 52.877545 56.535931 57.950145
## [12] 59.068179
但我想提供一个开放的均匀结向量,以便将拟合锚定到第一个和最后一个点——使用df
不支持这一点。
据我所知,对于给定的点集,以及样条曲线的3阶,必须有(12-1)+3+2 = 16
个节点(每m=n+p+1,对于#knot=m+1,#control=n+1,degree=p),所以对于一个夹紧的样条曲线,这应该是一个很好的节点向量:
knots <- seq(path$distance[1], path$distance[12], length.out = 10)
knots <- c(rep(knots[1], 3), knots, rep(knots[10], 3))
knots
## [1] 0.000000 0.000000 0.000000 0.000000 6.563131 13.126262 19.689393 26.252524 32.815655
## [10] 39.378786 45.941917 52.505048 59.068179 59.068179 59.068179 59.068179
然而,使用它会给出一些疯狂的数字,以及关于等级不足的警告,所以很明显,我一定错了:
pred_df <- data.frame(x=0,y=0,distance=seq(min(path$distance), max(path$distance), length.out=100))
xPath <- predict(lm(x~bs(distance, knots=knots, degree = 3), path), pred_df)
## Warning message:
## In predict.lm(lm(x ~ bs(distance, knots = knots, degree = degree), :
## prediction from a rank-deficient fit may be misleading
summary(xPath)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -2133.000 3.468 16.700 -161.900 64.590 857.800
在给定一组控制点和度数的情况下,指定结向量的正确方法是什么?
从"parameter"one_answers"knots"数据判断,它们确实违反了Schoenberg-Whitney条件。我不熟悉R中的语法,但似乎您正在路径$distance[1]和路径$distance[12]之间统一生成结值。这是不对的。您应该以以下方式生成结值:
0)将参数表示为p[i],其中i=0到(n-1),p[0]=0.0,n为点数。对于您的情况,n=12
1) 将结值创建为
knot[0]=(p[1]+p[2]+p[3])/3
knot[1]=(p[2]+p[3]+p[4])/3
knot[2]=(p[3]+p[4]+p[5])/3
……
这些是内部结值。您应该注意到,p[0]和p[n-1]将不会在此步骤中使用。您应该为您的案例获得8个内部结值
2) 现在,将p[0]添加到结值的前面4次(对于次数=3),将p[n-1]添加到结的末尾4次,就完成了。对于您的情况,您总共应该得到16个结值。
请注意,这不是生成有效结向量的唯一方法。但以这种方式生成的结向量将始终满足绍恩伯格-惠特尼条件。