我正在寻找(最好是内置的)Matlab函数,以与R中相同的方式计算B样条基矩阵,例如对于具有20个等距节点和3次的样条基,我在R中会这样做:
require(splines)
B = bs(x = seq(0,1,length.out=100),
knots = seq(0, 1, length.out=20), # 20 knots
degree = 3,
intercept = FALSE)
matplot(B,type="l")
为了在Matlab中得到相同的结果,我认为可以使用
B = spcol(linspace(0,1,20),3,linspace(0,1,100));
plot(B);
但是可以看到边界结点缺失了。 有没有想法,在Matlab中获得与R相同的等效语法?
PS R用于bs()
的代码略有简化:
basis <- function(x, degree, i, knots) {
if(degree == 0){
B <- ifelse((x >= knots[i]) & (x < knots[i+1]), 1, 0)
} else {
if((knots[degree+i] - knots[i]) == 0) {
alpha1 <- 0
} else {
alpha1 <- (x - knots[i])/(knots[degree+i] - knots[i])
}
if((knots[i+degree+1] - knots[i+1]) == 0) {
alpha2 <- 0
} else {
alpha2 <- (knots[i+degree+1] - x)/(knots[i+degree+1] - knots[i+1])
}
B <- alpha1*basis(x, (degree-1), i, knots) + alpha2*basis(x, (degree-1), (i+1), knots)
}
return(B)
}
bs <- function(x, degree=3, interior.knots=NULL, intercept=FALSE, Boundary.knots = c(0,1)) {
if(missing(x)) stop("You must provide x")
if(degree < 1) stop("The spline degree must be at least 1")
Boundary.knots <- sort(Boundary.knots)
interior.knots.sorted <- NULL
if(!is.null(interior.knots)) interior.knots.sorted <- sort(interior.knots)
knots <- c(rep(Boundary.knots[1], (degree+1)), interior.knots.sorted, rep(Boundary.knots[2], (degree+1)))
K <- length(interior.knots) + degree + 1
B.mat <- matrix(0,length(x),K)
for(j in 1:K) B.mat[,j] <- basis(x, degree, j, knots)
if(any(x == Boundary.knots[2])) B.mat[x == Boundary.knots[2], K] <- 1
if(intercept == FALSE) {
return(B.mat[,-1])
} else {
return(B.mat)
}
}