testthat::context("testing GP kernel functions") #--- on sampled data, fitted derivative and true derivative are similar ---- #' the variance of derivative seems wrong xtime <- seq(0,20,0.1) phitrue <- list( compact1 = c(2.618, 6.381, 0.152, 9.636), rbf = c(0.838, 0.307, 0.202, 0.653), matern = c(2.04, 1.313, 0.793, 3.101), periodicMatern = c(2.04, 1.313, 9, 0.793, 3.101, 9), generalMatern = c(2.04, 1.313, 0.793, 3.101), rationalQuadratic = c(85.278, 5.997, 35.098, 14.908) ) uprange <- 3.5 downrange <- 0.3 set.seed(123) for(kerneltype in c("compact1","rbf","matern","periodicMatern","generalMatern", "rationalQuadratic")){ if(kerneltype=="rationalQuadratic") downrange <- 0.06 testthat::test_that("check Cprime and Cdoubleprime", { xtime <- seq(0,2,0.01) delta <- mean(diff(xtime)) egcov2 <- calCov(head(phitrue[[kerneltype]], length(phitrue[[kerneltype]])/2), as.matrix(dist(xtime)), -sign(outer(xtime,xtime,'-')), kerneltype = kerneltype) testthat::expect_equal( (egcov2$Cprime[-1,1] + egcov2$Cprime[-nrow(egcov2$Cprime),1])/2, diff(egcov2$C[,1])/delta, tolerance = 0.0001, scale=max(abs(egcov2$Cprime[-1,1]))) testthat::expect_equal( (egcov2$Cdoubleprime[-1,1] + egcov2$Cdoubleprime[-nrow(egcov2$Cdoubleprime),1])/2, -diff(egcov2$Cprime[,1])/0.01, tolerance = 0.001, scale=max(abs(egcov2$Cdoubleprime[-1,1]))) }) testthat::test_that("check dCdphi", { if(kerneltype == "periodicMatern") skip("periodicMatern dCdphi is wrong for the 3rd parameter") xtime <- seq(0,2,0.1) testpintPhi <- head(phitrue[[kerneltype]], length(phitrue[[kerneltype]])/2) delta <- 1e-4 egcov0 <- calCov(testpintPhi, as.matrix(dist(xtime)), -sign(outer(xtime,xtime,'-')), kerneltype = kerneltype) for(it in 1:length(testpintPhi)){ testpintPhi1 <- testpintPhi testpintPhi1[it] <- testpintPhi1[it] + delta egcov1 <- calCov(testpintPhi1, as.matrix(dist(xtime)), -sign(outer(xtime,xtime,'-')), kerneltype = kerneltype) expect_equal((egcov1$C - egcov0$C)/delta, egcov0$dCdphiCube[,,it], tolerance = 1e-3, scale = max(abs(egcov0$dCdphiCube[,,it]))) } }) curCovV <- calCov(head(phitrue[[kerneltype]], length(phitrue[[kerneltype]])/2), as.matrix(dist(xtime)), -sign(outer(xtime,xtime,'-')), kerneltype = kerneltype) curCovR <- calCov(tail(phitrue[[kerneltype]], length(phitrue[[kerneltype]])/2), as.matrix(dist(xtime)), -sign(outer(xtime,xtime,'-')), kerneltype = kerneltype) fn.true <- read.csv(system.file("testdata/FN.csv", package="magi")) fn.true$time <- fn.true$time <- seq(0,20,0.05) abc <- c(0.2, 0.2, 3) fn.true$dVtrue = with(fn.true, abc[3] * (Vtrue - Vtrue^3/3.0 + Rtrue)) fn.true$dRtrue = with(fn.true, -1.0/abc[3] * (Vtrue - abc[1] + abc[2]*Rtrue)) # V draws <- MASS::mvrnorm(7, rep(0, length(xtime)), curCovV$C) plot(fn.true$time, fn.true$Vtrue, lwd=2, type="l") matplot(xtime, t(draws), type="l", lty = 2:8, col= 2:8, add=T) mtext(paste("V -", kerneltype)) testthat::test_that(paste("level shoule be in the range -",kerneltype), { rangeRatio <- range(fn.true$Vtrue) / range(draws) expect_lt(max(rangeRatio), uprange) expect_gt(min(rangeRatio), downrange) }) x <- draws[1,] dxNum <- c(diff(head(x,2))/(xtime[2]-xtime[1]), (x[-(1:2)]-x[1:(length(x)-2)])/(xtime[3]-xtime[1]), diff(tail(x,2))/(xtime[2]-xtime[1])) dxMean <- curCovV$mphi%*%x plot(xtime, dxNum, type="l", main="derivative") lines(xtime, dxMean, col=2) mtext(paste("V -", kerneltype)) test_that(paste("check if derivative variance Kmat too small: V of FN - ", kerneltype),{ if(kerneltype == "rbf") skip("rbf derivative variance Kmat too small") if(kerneltype == "rationalQuadratic") skip("rationalQuadratic derivative variance Kmat too small") expect_lt(mean(abs((dxNum-dxMean)/sqrt(diag(curCovR$Kphi)))), 20) }) testthat::test_that(paste("derivative difference should be small on the eye -",kerneltype), { expect_lt(mean(abs((dxNum - dxMean)[2:(length(dxMean)-1)]/diff(range(dxMean)))),0.05) }) # R draws <- MASS::mvrnorm(7, rep(0, length(xtime)), curCovR$C) plot(fn.true$time, fn.true$Rtrue, lwd=2, type="l") matplot(xtime, t(draws), type="l", lty = 2:8, col= 2:8, add=T) mtext(paste("R -", kerneltype)) testthat::test_that(paste("level shoule be in the range -",kerneltype), { rangeRatio <- range(fn.true$Vtrue) / range(draws) expect_lt(max(rangeRatio), uprange) expect_gt(min(rangeRatio), downrange) }) x <- draws[1,] dxNum <- c(diff(head(x,2))/(xtime[2]-xtime[1]), (x[-(1:2)]-x[1:(length(x)-2)])/(xtime[3]-xtime[1]), diff(tail(x,2))/(xtime[2]-xtime[1])) dxMean <- curCovR$mphi%*%x plot(xtime, dxNum, type="l", main="derivative") lines(xtime, dxMean, col=2) mtext(paste("R -", kerneltype)) test_that(paste("check if derivative variance Kmat too small: R of FN - ", kerneltype),{ if(kerneltype == "rbf") skip("rbf derivative variance Kmat too small") expect_lt(mean(abs((dxNum-dxMean)/sqrt(diag(curCovR$Kphi)))), 10) }) testthat::test_that(paste("derivative difference should be small on the eye -",kerneltype), { expect_lt(mean(abs((dxNum - dxMean)[2:(length(dxMean)-1)]/diff(range(dxMean)))),0.05) }) #--- on real data, fitted derivative and true derivative are quite different ---- fn.true <- fn.true[seq(1,401,2),] # V x <- fn.true$Vtrue Ctrue <- curCovV$C dxNum <- fn.true$dVtrue dxMean <- curCovV$mphi%*%x plot(fn.true$time, dxNum, type="l") lines(fn.true$time, dxMean, col=2) plot((dxNum - dxMean)/sqrt(diag(curCovV$Kphi)), type="l") testthat::test_that(paste("derivative difference should be small on the eye - realdata ",kerneltype), { expect_lt(mean(abs((dxNum - dxMean)[2:(length(dxMean)-1)]/diff(range(dxMean)))),0.01) }) test_that(paste("check if derivative variance Kmat too small: realdata V of FN - ", kerneltype),{ expect_lt(mean(abs((dxNum-dxMean)/sqrt(diag(curCovV$Kphi)))), 5) }) # R x <- fn.true$Rtrue dxNum <- fn.true$dRtrue dxMean <- curCovR$mphi%*%x plot((dxNum - dxMean)/sqrt(diag(curCovR$Kphi)), type="l") testthat::test_that(paste("derivative difference should be small on the eye - realdata ",kerneltype), { expect_lt(mean(abs((dxNum - dxMean)[2:(length(dxMean)-1)]/diff(range(dxMean)))),0.01) }) test_that(paste("check if derivative variance Kmat too small: realdata R of FN - ", kerneltype),{ if(kerneltype == "rationalQuadratic") skip("rationalQuadratic derivative variance Kmat too small") testthat::expect_lt(mean(abs((dxNum-dxMean)/sqrt(diag(curCovR$Kphi)))), 5) }) } testthat::test_that("linear kernel gives linear curve", { xtime <- seq(0,5,0.1) egcov <- magi:::calCovLinear(c(1,1), xtime, complexity = 0) draws <- MASS::mvrnorm(7, rep(0, length(xtime)), egcov$C) matplot(xtime, t(draws), type="l", lty = 2:8, col= 2:8) mtext("linear kernel") diffdraws <- t(diff(t(draws))) testthat::expect_true(all(abs(diffdraws - rowMeans(diffdraws)) < 1e-5)) # can be reparametrized to be translation invariant if SigmaMat is not diagonal }) testthat::test_that("Neural Network kernel gives rapid changes around 0", { xtime <- seq(-4,4,0.1) egcov <- magi:::calCovNeuralNetwork(c(1,1), xtime, complexity = 0) draws <- MASS::mvrnorm(7, rep(0, length(xtime)), egcov$C) matplot(xtime, t(draws), type="l", lty = 2:8, col= 2:8) title("Neural Network kernel") mtext("not suitable for us: don't know fast moving part a priori") }) testthat::test_that("Warping Matern kernel with sin/cos", { xtime <- seq(-2,5,0.1) periodicity <- 2 r <- as.matrix(dist(xtime)) signr <- -sign(outer(xtime, xtime, "-")) egcov2 <- magi:::calCovPeriodicWarpMatern(c(1,1, periodicity), r, signr, complexity = 3) draws <- MASS::mvrnorm(2, rep(0, length(xtime)), egcov2$C) matplot(xtime, t(draws), type="l", lty = 2:8, col= 2:8) title("Warping Matern kernel with sin/cos") }) testthat::test_that("modulated squared exponential kernel", { xtime <- seq(-6,6,0.1) egcov <- magi:::calCovModulatedRBF(c(1,1,1), xtime, complexity = 0) draws <- MASS::mvrnorm(7, rep(0, length(xtime)), egcov$C) matplot(xtime, t(draws), type="l", lty = 2:8, col= 2:8) title("modulated squared exponential kernel") mtext("not suitable for us: don't have tightening at both ends") }) testthat::test_that("Rational Quadratic kernel", { xtime <- seq(-2,5,0.1) r <- as.matrix(dist(xtime)) signr <- -sign(outer(xtime, xtime, "-")) egcov2 <- magi:::calCovRationalQuadratic(c(1,1), r, signr, complexity = 3) draws <- MASS::mvrnorm(7, rep(0, length(xtime)), egcov2$C) matplot(xtime, t(draws), type="l", lty = 2:8, col= 2:8) title("Rational Quadratic kernel") mtext("could be promising") })