Specify clamped knot vector in bs-call

随声附和 提交于 2019-12-02 17:26:29

问题


I intend to fit a clamped b-spline to a set of control points in R, but have trouble understanding the use of the knots parameter in bs. Given a set of control points:

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)
)

I fit x and y independently against the distance along the path:

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

but I want to provide an open uniform knot vector in order to anchor the fit to the first and last point - using df does not support this.

As I understand it, for my given set of points, and a degree of 3 for the spline, there must be (12-1)+3+2 = 16 knots (per m=n+p+1, for #knots=m+1, #control=n+1, degree=p), so for a clamped spline, this should be a nice knot vector:

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

using this gives some crazy numbers though, as well as a warning about rank-deficiency, so clearly I must have it wrong somehow:

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 

What is the correct way to specify the knot-vector given a set of control points and a degree?


回答1:


Judging from your 'parameter' and 'knots' data, indeed they violate the Schoenberg-Whitney condition. I am not familiar with the syntax in R, but it seems that you are generating the knot values uniformly between path$distance[1] and path$distance[12]. This is not right. You should generate your knot values in the following way:

0) Denote the parameters as p[i], where i = 0 to (n-1), p[0]=0.0 and n is number of points. For your case, n=12
1) Create the knot values as

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
......
These are the interior knot values. You should notice that p[0] and p[n-1] will not be used in this step. You should obtain 8 interior knot values for your case.
2) Now, add p[0] to the front of the knot values 4 times (for degree=3) and add p[n-1] to the end of the knot values 4 times and you are done. For your case, you should get 16 knot values in total.

Please note that this is not the only way to generate a valid knot vector. But knot vector generated in this way will always satisfy the Shoenberg-Whitney condition.



来源:https://stackoverflow.com/questions/33609538/specify-clamped-knot-vector-in-bs-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!