Thanks to both of you.
I already tried the interpol1Dfun approach and it was very unstable and did not seem to work. Hence in this case I would like to use the fact that B-spline derivatives are "easy" to have the correct interpolation.
I worked on it and figured out the only implementing a function for the (flattened) basis matrix is probably easier and it seems to work perfectly:
# second derivative with derivative
ddb <- ADjoint(
function(x) {
ddB_interp <- sapply(1:ncol(ddB_fine), function(j) approx(xfine, ddB_fine[, j], xout = x, rule = 2)$y)
as.numeric(ddB_interp)
},
function(x, y, dy) {
dddB_interp <- sapply(1:ncol(dddB_fine), function(j) approx(xfine, dddB_fine[, j], xout = x, rule = 2)$y)
dy_mat <- matrix(dy, ncol = k)
rowSums(dy_mat * dddB_interp)
},
name = "ddb"
)
# derivative with derivative
db <- ADjoint(
function(x) {
dB_interp <- sapply(1:ncol(dB_fine), function(j) approx(xfine, dB_fine[, j], xout = x, rule = 2)$y)
as.numeric(dB_interp)
},
function(x, y, dy) {
ddB_interp <- matrix(ddb(x), ncol = k)
dy_mat <- matrix(dy, ncol = k)
rowSums(dy_mat * ddB_interp)
},
name = "db"
)
# B-spline with derivative
b <- ADjoint(
function(x) {
B_interp <- sapply(1:ncol(B_fine), function(j) approx(xfine, B_fine[, j], xout = x, rule = 2)$y)
as.numeric(B_interp)
},
function(x, y, dy) {
dB_interp <- matrix(db(x), ncol = k)
dy_mat <- matrix(dy, ncol = k)
rowSums(dy_mat * dB_interp)
},
name = "b"
)
# matrix format
B <- function(x) matrix(b(x), ncol = k)
par <- sin(1:k)
x <- 1:9
f <- function(xpar) {
x <- xpar[1:(length(xpar) - k)]
par <- xpar[(length(xpar) - k + 1):length(xpar)]
B(x) %*% par
}
xpar <- c(x, par)
F <- MakeTape(f, xpar)
FF <- F$jacfun(sparse = TRUE)
FF(xpar)
FFF <- F$jacfun(sparse = TRUE)
FFF(xpar)
B_fine, dB_fine, ddB_fine, and dddB_fine are pre-evaluated basis matrices.
The only issue I have with the approach above is that it doesn't allow for sparsity, which I also need. Do you think that's easy to incorporate?