Nothing
## To-do
## Check atomics with some care.
## replace CppADround with nimDerivs_round
## This file had a major update from an earlier "version 1" to "version 2" in spring 2022.
## Version 1 portions are commented out but retained for easy reference.
###################
## create R aliases
###################
## could instead use an inverted version of nimble:::specificCallReplacements in
## test_AD but for now we need to ensure there is an R function with the same
## name as every operator tested.
## In addition there are now three variants of all tests:
## 1. Just the function itself, f(x) (potentially with variations in argument types)
## 2. The function with a nested argument, f(g(x))
## 3. The function as a nested argument, g(f(x))
## The nested cases are important because the invoke less trivial use of CppAD
## forward and backward mode calculations. The choice of c() in both cases
## is to have non-trivial (and non-constant) derivatives itself to second order
## while not throwing result values into difficult regions.
## Testing relies on comparisons among R-vs-R (to a minimal extent in these tests),
## R-vs-C, and C-vs-C (in various modes of obtaining derivatives).
## The R-vs-C in particular makes it tricky to choose tolerances for verification
## that are not too loose or too tight.
gammafn <- gamma
lgammafn <- lgamma
ceil <- ceiling
ftrunc <- trunc
squaredNorm <- function(x) sum(x^2)
##################
## unary cwise ops
##################
# unaryArgs <- c('double(0)', 'double(1, 4)', 'double(2, c(3, 4))')
unaryOps <- c(
'-', nimble:::unaryDoubleOperators,
nimble:::unaryPromoteNoLogicalOperators
)
## Split into those involving atomics and not as we want to run both 'inner' and 'outer' on the atomics,
## but that would take a long time if doing so on all unaryOps.
unaryAtomicOps <- c('probit','iprobit','gammafn','lgammafn','lfactorial','factorial',
'nimRound','ftrunc','ceil','floor')
unaryOps <- unaryOps[!unaryOps %in% unaryAtomicOps]
## # old versions
## unaryOpTests <- make_AD_test_batch(
## unaryOps, unaryArgs
## )
## ## tranform args
## modify_on_match(unaryOpTests, '(log|sqrt) .+', 'input_gen_funs', function(x) abs(rnorm(x)))
## modify_on_match(unaryOpTests, 'log1p .+', 'input_gen_funs', function(x) abs(rnorm(x)) - 1)
## modify_on_match(unaryOpTests, '(logit|probit|cloglog) .+', 'input_gen_funs', runif)
## modify_on_match(unaryOpTests, '(acos|asin|atanh) .+', 'input_gen_funs', function(x) runif(x, -1, 1))
## modify_on_match(unaryOpTests, 'acosh .+', 'input_gen_funs', function(x) abs(rnorm(x)) + 1)
unaryArgs2 <- c('double(0)', 'double(1)', 'double(2)')
set.seed(123) # seed for randomly generating seeds for each test
unaryOpTests2 <- make_AD_test_batch(
unaryOps, unaryArgs2, maker = make_AD_test2
)
modify_on_match(unaryOpTests2, '(log|sqrt) .+', 'input_gen_funs', function(x) abs(rnorm(x)))
modify_on_match(unaryOpTests2, 'log1p .+', 'input_gen_funs', function(x) abs(rnorm(x)) - 1)
modify_on_match(unaryOpTests2, '(logit|cloglog) .+', 'input_gen_funs', function(x) runif(x, 0.05, .95))
modify_on_match(unaryOpTests2, '(acos|asin|atanh) .+', 'input_gen_funs', function(x) runif(x, -0.95, 0.95))
modify_on_match(unaryOpTests2, 'acosh .+', 'input_gen_funs', function(x) abs(rnorm(x)) + 1)
modify_on_match(unaryOpTests2, '^cos .+', 'input_gen_funs', function(x) runif(x, 1, 3)) # Avoid high 2nd derivs b/c numerical gradient is inaccurate three
modify_on_match(unaryOpTests2, '^tan .+', 'input_gen_funs', function(x) runif(x, -1.5, 1.5)) #Avoid pi/2=1.57
modify_on_match(unaryOpTests2, '^cosh .+', 'input_gen_funs', function(x) sample(c(-1,1), size = x, replace = TRUE) * runif(x, .2, 1.2)) # Avoid high 2nd derivs b/c numerical gradient is inaccurate there
modify_on_match(unaryOpTests2, '^tanh .+', 'input_gen_funs', function(x) runif(x, -0.8, 0.8)) # Avoid flat rmodify_on_match(unaryOpTests2, '^sin .+', 'input_gen_funs', function(x) runif(x, -1, 1))
modify_on_match(unaryOpTests2, '^cube .+', 'input_gen_funs', function(x) sample(c(seq(-1.5, -.2, length = 20), seq(.2, 1.5, length = 20)), size = x, replace = TRUE))
###########################################################
# f(g(x)) where f is function being tested and g(x) = x^3
set.seed(123) # Ok to use same as above
unaryOpTests2_inner <- make_AD_test_batch(
unaryOps, unaryArgs2, maker = make_AD_test2, inner_codes = list(quote(X*X*X))
)
# ADtestEnv$RCrelTol <- c(1e-15, 1e-4, 1e-2) ## Loosen tols because there are more operations
sCbRt <- function(x) sign(x) * abs(x)^(1/3) #signed cube root. This preserves sign and scale of input to f since g(x) = x^3
modify_on_match(unaryOpTests2_inner, '(log|sqrt) .+', 'input_gen_funs', function(x) abs(rnorm(x)))
modify_on_match(unaryOpTests2_inner, 'log1p .+', 'input_gen_funs', function(x) sCbRt(abs(rnorm(x)) - 1))
modify_on_match(unaryOpTests2_inner, '(logit|cloglog) .+', 'input_gen_funs', function(x) sCbRt(runif(x, 0.05, 0.95)))
modify_on_match(unaryOpTests2_inner, '(acos|asin|atanh) .+', 'input_gen_funs', function(x) sCbRt(runif(x, -0.95, 0.95)))
modify_on_match(unaryOpTests2_inner, 'acosh .+', 'input_gen_funs', function(x) sCbRt(abs(rnorm(x)) + 1.05))
modify_on_match(unaryOpTests2_inner, '^cos .+', 'input_gen_funs', function(x) sCbRt(runif(x, 1, 3))) # Avoid high 2nd derivs b/c numerical gradient is inaccurate there
modify_on_match(unaryOpTests2_inner, '^cosh .+', 'input_gen_funs', function(x) sCbRt(sample(c(-1,1), size = x, replace = TRUE) * runif(x, .2, 1.2))) # Avoid high 2nd derivs b/c numerical gradient is inaccurate there
modify_on_match(unaryOpTests2_inner, '^tanh .+', 'input_gen_funs', function(x) sCbRt(runif(x, -0.8, 0.8))) # Avoid flat regions
modify_on_match(unaryOpTests2_inner, '^sin .+', 'input_gen_funs', function(x) sCbRt(runif(x, -1, 1)))
modify_on_match(unaryOpTests2_inner, '^tan .+', 'input_gen_funs', function(x) sCbRt(runif(x, -1.5, 1.5))) #Avoid pi/2=1.57
modify_on_match(unaryOpTests2_inner, '^cube .+', 'input_gen_funs', function(x) sCbRt(sample(c(seq(-1.5, -.2, length = 20), seq(.2, 1.5, length = 20)), size = x, replace = TRUE)))
###########################################################
# g(f(x)) where f is function being tested and g(y) is exp(.5 * y)
set.seed(123) # Ok to use same as above
unaryOpTests2_outer <- make_AD_test_batch(
unaryOps, unaryArgs2, maker = make_AD_test2, outer_code = quote(exp(0.5 * Y))
)
#ADtestEnv$RCrelTol <- c(1e-15, 1e-6, 1e-2)
modify_on_match(unaryOpTests2_outer, '(log|sqrt) .+', 'input_gen_funs', function(x) abs(rnorm(x)))
modify_on_match(unaryOpTests2_outer, 'log1p .+', 'input_gen_funs', function(x) abs(rnorm(x)) - 1)
modify_on_match(unaryOpTests2_outer, '(logit|cloglog) .+', 'input_gen_funs', function(x) runif(x, 0.05, .95))
modify_on_match(unaryOpTests2_outer, '(acos|asin|atanh) .+', 'input_gen_funs', function(x) runif(x, -0.95, 0.95))
modify_on_match(unaryOpTests2_outer, 'acosh .+', 'input_gen_funs', function(x) abs(rnorm(x)) + 1)
modify_on_match(unaryOpTests2_outer, '^cos .+', 'input_gen_funs', function(x) runif(x, 1, 3)) # Avoid high 2nd derivs b/c numerical gradient is inaccurate three
modify_on_match(unaryOpTests2_outer, '^cosh .+', 'input_gen_funs', function(x) sample(c(-1,1), size = x, replace = TRUE) * runif(x, .2, 1.2)) # Avoid high 2nd derivs b/c numerical gradient is inaccurate there
modify_on_match(unaryOpTests2_outer, '^tanh .+', 'input_gen_funs', function(x) runif(x, -0.8, 0.8)) # Avoid flat regions
modify_on_match(unaryOpTests2_outer, '^sin .+', 'input_gen_funs', function(x) runif(x, -1, 1))
modify_on_match(unaryOpTests2_outer, '^tan .+', 'input_gen_funs', function(x) runif(x, -1.5, 1.5)) #Avoid pi/2=1.57
modify_on_match(unaryOpTests2_outer, '^cube .+', 'input_gen_funs', function(x) sample(c(seq(-1.5, -.2, length = 20), seq(.2, 1.5, length = 20)), size = x, replace = TRUE))
## Now set up equivalent tests for atomics.
set.seed(1234) # seed for randomly generating seeds for each test (using `123` gives tolerance issues; may want to look into)
unaryAtomicOpTests2 <- make_AD_test_batch(
unaryAtomicOps, unaryArgs2, maker = make_AD_test2
)
modify_on_match(unaryAtomicOpTests2, 'probit .+', 'input_gen_funs', function(x) runif(x, 0.05, .95))
modify_on_match(unaryAtomicOpTests2, '(factorial|factorial) .+', 'input_gen_funs', function(x) sample(3:10, size = x, replace = TRUE))
gamma_x_vals <- c(-1.8, -1.4, -0.9, -0.2, 0.2, 0.8, 1, 1.2, 2, 2.5)
modify_on_match(unaryAtomicOpTests2, '^gammafn .+', 'input_gen_funs', function(x) sample(gamma_x_vals, size = x, replace = TRUE))
###########################################################
# f(g(x)) where f is function being tested and g(x) = x^3
set.seed(1234) # Ok to use same as above
unaryAtomicOpTests2_inner <- make_AD_test_batch(
unaryAtomicOps, unaryArgs2, maker = make_AD_test2, inner_codes = list(quote(X*X*X))
)
# ADtestEnv$RCrelTol <- c(1e-15, 1e-4, 1e-2) ## Loosen tols because there are more operations
modify_on_match(unaryAtomicOpTests2_inner, 'probit .+', 'input_gen_funs', function(x) sCbRt(runif(x, 0.05, 0.95)))
modify_on_match(unaryAtomicOpTests2_inner, '(factorial|factorial) .+', 'input_gen_funs', function(x) sample(1:3, size = x, replace = TRUE))
modify_on_match(unaryAtomicOpTests2_inner, '^gammafn .+', 'input_gen_funs', function(x) sCbRt(sample(gamma_x_vals, size = x, replace = TRUE)))
###########################################################
# g(f(x)) where f is function being tested and g(y) is exp(.5 * y)
set.seed(1234) # Ok to use same as above
unaryAtomicOpTests2_outer <- make_AD_test_batch(
unaryAtomicOps, unaryArgs2, maker = make_AD_test2, outer_code = quote(exp(0.5 * Y))
)
#ADtestEnv$RCrelTol <- c(1e-15, 1e-6, 1e-2)
modify_on_match(unaryAtomicOpTests2_outer, 'probit .+', 'input_gen_funs', function(x) runif(x, 0.05, .95))
modify_on_match(unaryAtomicOpTests2_outer, '(factorial|factorial) .+', 'input_gen_funs', function(x) sample(1:3, size = x, replace = TRUE))
modify_on_match(unaryAtomicOpTests2_outer, '^gammafn .+', 'input_gen_funs', function(x) sample(gamma_x_vals, size = x, replace = TRUE))
######################
## unary reduction ops
######################
# nimble:::reductionUnaryOperatorsArray contains only sd and var
# but var(matrix) is not supported because, per note in size processing code,
# in R var(matrix) is interpeted as cov(data.frame) and so it really different.
unaryReductionOps <- c(
'sum', nimble:::reductionUnaryDoubleOperatorsEither,
'sd' # Add 'var' below without matrix input
)
## unaryReductionArgs <- c('double(1, 4)', 'double(2, c(3, 4))')
## unaryReductionOpTests <- make_AD_test_batch(
## unaryReductionOps, unaryReductionArgs
## )
## unaryReductionOpTests <- c(unaryReductionOpTests,
## make_AD_test_batch('var', unaryReductionArgs[1]))
unaryReductionArgs2 <- c('double(1)', 'double(2)')
set.seed(123) # Ok to use same as above
unaryReductionOpTests2 <- make_AD_test_batch(
unaryReductionOps, unaryReductionArgs2, maker = make_AD_test2
)
unaryReductionOpTests2 <- c(unaryReductionOpTests2,
make_AD_test_batch(
'var', unaryReductionArgs2[1], maker = make_AD_test2))
modify_on_match(unaryReductionOpTests2, 'arg1 = double\\(2\\)',
'RCrelTol', c(1e-13, 1e-5, 1e-3) ) ## lower tol for matrix (larger) inputs
#res <- lapply(unaryReductionOpTests2, test_AD2)
## f(g(x))
set.seed(123) # Ok to use same as above
unaryReductionOpTests2_inner <- make_AD_test_batch(
unaryReductionOps, unaryReductionArgs2, maker = make_AD_test2, inner_codes = list(quote(X*X*X))
)
unaryReductionOpTests2_inner <- c(unaryReductionOpTests2_inner,
make_AD_test_batch(
'var', unaryReductionArgs2[1], maker = make_AD_test2, inner_codes = list(quote(X*X*X))))
modify_on_match(unaryReductionOpTests2_inner, 'sum .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
modify_on_match(unaryReductionOpTests2_inner, 'mean .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
modify_on_match(unaryReductionOpTests2_inner, 'squaredNorm .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
modify_on_match(unaryReductionOpTests2_inner, 'prod .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
modify_on_match(unaryReductionOpTests2_inner, 'sd .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
modify_on_match(unaryReductionOpTests2_inner, 'var .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
## g(f(x)
set.seed(123) # Ok to use same as above
unaryReductionOpTests2_outer <- make_AD_test_batch(
unaryReductionOps, unaryReductionArgs2, maker = make_AD_test2, outer_code = quote(exp(0.5 * Y))
)
unaryReductionOpTests2_outer <- c(unaryReductionOpTests2_outer,
make_AD_test_batch(
'var', unaryReductionArgs2[1], maker = make_AD_test2, outer_code = quote(exp(0.5 * Y))))
modify_on_match(unaryReductionOpTests2_outer, 'sum .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
modify_on_match(unaryReductionOpTests2_outer, 'mean .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
modify_on_match(unaryReductionOpTests2_outer, 'squaredNorm .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
modify_on_match(unaryReductionOpTests2_outer, 'prod .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
modify_on_match(unaryReductionOpTests2_outer, 'sd .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
modify_on_match(unaryReductionOpTests2_outer, 'var .+', 'input_gen_funs', function(x) runif(x, .5, 1.5))
#############
## binary ops
#############
## does not include combinations of vector and matrix
## binaryArgs <- as.list(
## cbind(
## data.frame(t(expand.grid(unaryArgs[1], unaryArgs)), stringsAsFactors=FALSE),
## data.frame(t(expand.grid(unaryArgs[2:3], unaryArgs[1])), stringsAsFactors=FALSE)
## )
## )
## names(binaryArgs) <- NULL
## binaryArgs[[length(binaryArgs) + 1]] <- rep(unaryArgs[2], 2)
## binaryArgs[[length(binaryArgs) + 1]] <- rep(unaryArgs[3], 2)
binaryArgs2 <- as.list(
cbind(
data.frame(t(expand.grid(unaryArgs2[1], unaryArgs2)), stringsAsFactors=FALSE),
data.frame(t(expand.grid(unaryArgs2[2:3], unaryArgs2[1])), stringsAsFactors=FALSE)
)
)
names(binaryArgs2) <- NULL
binaryArgs2[[length(binaryArgs2) + 1]] <- rep(unaryArgs2[2], 2)
binaryArgs2[[length(binaryArgs2) + 1]] <- rep(unaryArgs2[3], 2)
binaryOps <- c(
nimble:::binaryOrUnaryOperators,
'/', '*', '%%' # %% is not supported and is on knownFailures list
)
## binaryOpTests <- make_AD_test_batch(
## binaryOps, binaryArgs
## )
## modify_on_match(binaryOpTests, "/ arg1 = double\\(0\\) arg2 = double\\(2, c\\(3, 4\\)\\)", 'input_gen_funs', function(x) {res <- rnorm(x);res <- res + sign(res)*0.1; res}) ## This generator avoids small numbers that, in the denominator, give huge hes
set.seed(123)
binaryOpTests2 <- make_AD_test_batch(
binaryOps, binaryArgs2, maker = make_AD_test2
)
modify_on_match(binaryOpTests2, "/ arg1 = double\\(0\\) arg2 = double\\(2\\)", 'input_gen_funs',
function(x) {res <- rnorm(x);res <- res + sign(res)*0.1; res}) ## This generator avoids small numbers that, in the denominator, give huge hessians that are hard to numerically match from finite elements
## f(g(x1), g(x2))
set.seed(123)
binaryOpTests2_inner <- make_AD_test_batch(
binaryOps, binaryArgs2, maker = make_AD_test2, inner_codes = list(quote(X*X*X), quote(X*X*X))
)
modify_on_match(binaryOpTests2_inner, "", 'input_gen_funs', function(x) {res <- rnorm(x);res <- res + sign(res)*0.1; res}) ## This generator avoids small numbers that, in the denominator, give huge
## g(f(x1, x2))
set.seed(123)
binaryOpTests2_outer <- make_AD_test_batch(
binaryOps, binaryArgs2, maker = make_AD_test2, outer_code = quote(exp(0.5 * Y))
)
modify_on_match(binaryOpTests2_outer, "", 'input_gen_funs', function(x) {res <- rnorm(x);res <- res + sign(res)*0.1; res}) ## This generator avoids small numbers that, in the denominator, give huge
## set tolerances (default is tol1 = 0.00001 and tol2 = 0.0001)
##modify_on_match(binaryOpTests, '(\\+|-) double\\(0\\) double\\(1, 4\\)', 'tol2', 0.001)
##modify_on_match(binaryOpTests, '(\\+|-) double\\(1, 4\\) double\\(0\\)', 'tol2', 0.001)
##modify_on_match(binaryOpTests, '(\\+|-) double\\(1, 4\\) double\\(1, 4\\)', 'tol2', 0.001)
## runtime failures
## example of specifying when a particular method fails:
## modify_on_match(
## binaryOpTests,
## '\\+ double\\(0\\) double\\(0\\)',
## 'knownFailures',
## list(
## method3 = list( ## arg1, arg2
## jacobian = expect_failure,
## hessian = expect_failure
## ),
## method4 = list( ## no wrt
## jacobian = expect_failure,
## hessian = expect_failure
## )
## )
## )
###############
## pow-like ops
###############
## powArgs <- list(
## c('double(0)', 'double(0)'),
## c('double(1, 4)', 'double(0)')
## )
## powOpTests <- make_AD_test_batch(
## powOps, powArgs
## )
## pow_int_OpTests <- list(
## make_AD_test(c('double(0)', 'integer(0)'), op = 'pow_int', wrt_args = 'arg1'),
## make_AD_test(c('double(1, 4)', 'integer(0)'), op = 'pow_int', wrt_args = 'arg1')
## )
powOps <- c(
'pow', '^'
)
powArgs2 <- list(
c('double(0)', 'double(0)'),
c('double(1)', 'double(0)'),
c('double(2)', 'double(0)')
)
powOpTests2 <- make_AD_test_batch(
powOps, powArgs2, maker = make_AD_test2
)
modify_on_match(powOpTests2, '', 'input_gen_funs', function(x) runif(x, .5, 1.5)) # a^b now defined only valid for both > 0
# TO-DO: TEST NON-INTEGER INPUT FOR b
# TO-DO: Add matrix^scalar case above
# This is a little delicated and should be explained in the manual.
# pow_int should still be given a double as a second argument or it will
# not end up flowing through the derivatives system correctly.
# There could be a crash, or, worse, incorrect results when the value is baked in.
pow_int_OpTests2 <- list(
make_AD_test2(c('double(0)', 'double(0)'), op = 'pow_int', wrt_args = c('arg1', 'arg2'),
input_gen_funs = list(arg1 = function(x) rnorm(x),
arg2 = function(x) sample(-3:3, size = x, replace = TRUE))),
make_AD_test2(c('double(1)', 'double(0)'), op = 'pow_int', wrt_args = c('arg1', 'arg2'),
input_gen_funs = list(arg1 = function(x) rnorm(x),
arg2 = function(x) sample(-3:3, size = x, replace = TRUE))),
make_AD_test2(c('double(2)', 'double(0)'), op = 'pow_int', wrt_args = c('arg1', 'arg2'),
input_gen_funs = list(arg1 = function(x) rnorm(x),
arg2 = function(x) sample(-3:3, size = x, replace = TRUE)))
)
## resetTols()
## res <- lapply(powOpTests2, test_AD2)
## res <- lapply(pow_int_OpTests2, test_AD2)
# f(g(x)). Use a different g than above because that is basically a power function
powOpTests2_inner <- make_AD_test_batch(
powOps, powArgs2, maker = make_AD_test2, inner_codes = list(quote(0.5*(exp(X/2)-1)), quote(1.1*X))
)
modify_on_match(powOpTests2_inner, '', 'input_gen_funs', function(x) runif(x, .5, 1.5)) # a^b now defined only valid for both > 0
pow_int_OpTests2_inner <- list(
make_AD_test2(c('double(0)', 'double(0)'), op = 'pow_int', wrt_args = c('arg1', 'arg2'),
input_gen_funs = list(arg1 = function(x) rnorm(x),
arg2 = function(x) sample(-3:3, size = x, replace = TRUE)),
inner_codes = list(quote(0.5*(exp(X/2)-1)), quote(1.1*X))),
make_AD_test2(c('double(1)', 'double(0)'), op = 'pow_int', wrt_args = c('arg1', 'arg2'),
input_gen_funs = list(arg1 = function(x) rnorm(x),
arg2 = function(x) sample(-3:3, size = x, replace = TRUE)),
inner_codes = list(quote(0.5*(exp(X/2)-1)), quote(1.1*X))),
make_AD_test2(c('double(2)', 'double(0)'), op = 'pow_int', wrt_args = c('arg1', 'arg2'),
input_gen_funs = list(arg1 = function(x) rnorm(x),
arg2 = function(x) sample(-3:3, size = x, replace = TRUE)),
inner_codes = list(quote(0.5*(exp(X/2)-1)), quote(1.1*X)))
)
# The 0.5*exp(X/2-1) is made up to give non-trivial derivs and some <0 and >0 values.
# The 1.1*X doesn't do much but checks that round(b) is used and at least isn't nothing.
## res <- lapply(powOpTests2, test_AD2)
## res <- lapply(pow_int_OpTests2, test_AD2)
# g(f(x))
powOpTests2_outer <- make_AD_test_batch(
powOps, powArgs2, maker = make_AD_test2, outer_code = quote(exp(0.5*Y))
)
modify_on_match(powOpTests2_outer, '', 'input_gen_funs', function(x) runif(x, .5, 1.5))
pow_int_OpTests2_outer <- list(
make_AD_test2(c('double(0)', 'double(0)'), op = 'pow_int', wrt_args = c('arg1', 'arg2'),
input_gen_funs = list(arg1 = function(x) sample(c(-1,1), size = x, replace=TRUE)*runif(x,.5,1.5),
arg2 = function(x) sample(-3:3, size = x, replace = TRUE)),
outer_code = quote(exp(0.5*Y))),
make_AD_test2(c('double(1)', 'double(0)'), op = 'pow_int', wrt_args = c('arg1', 'arg2'),
input_gen_funs = list(arg1 = function(x) sample(c(-1,1), size = x, replace=TRUE)*runif(x,.5,1.5),
arg2 = function(x) sample(-3:3, size = x, replace = TRUE)),
outer_code = quote(exp(0.5*Y))),
make_AD_test2(c('double(2)', 'double(0)'), op = 'pow_int', wrt_args = c('arg1', 'arg2'),
input_gen_funs = list(arg1 = function(x) sample(c(-1,1), size = x, replace=TRUE)*runif(x,.5,1.5),
arg2 = function(x) sample(-3:3, size = x, replace = TRUE)),
outer_code = quote(exp(0.5*Y)))
)
## res <- lapply(powOpTests2, test_AD2)
## res <- lapply(pow_int_OpTests2, test_AD2)
#######################
## binary reduction ops
#######################
binaryReductionArgs <- list(
c('double(1, 4)', 'double(1, 4)')
)
binaryReductionArgs2 <- list(
c('double(1)', 'double(1)')
)
binaryReductionOps <- nimble:::reductionBinaryOperatorsEither
binaryReductionOpTests <- make_AD_test_batch(
binaryReductionOps, binaryReductionArgs
)
binaryReductionOpTests2 <- make_AD_test_batch(
binaryReductionOps, binaryReductionArgs2, maker = make_AD_test2
)
resetTols()
## res <- lapply(binaryReductionOpTests2, test_AD2)
binaryReductionOpTests2_inner <- make_AD_test_batch(
binaryReductionOps, binaryReductionArgs2, maker = make_AD_test2,
inner_codes = list(quote(X*X*X), quote(X*X*X))
)
resetTols()
##ADtestEnv$RCrelTol <- c(1e-12, 1e-4, 1e-2)
##res <- lapply(binaryReductionOpTests2, test_AD2)
binaryReductionOpTests2_outer <- make_AD_test_batch(
binaryReductionOps, binaryReductionArgs2, maker = make_AD_test2,
outer_code = quote(exp(0.5*Y))
)
resetTols()
##ADtestEnv$RCrelTol <- c(1e-12, 1e-4, 1e-2)
##res <- lapply(binaryReductionOpTests2, test_AD2)
##########################
## unary square matrix ops
##########################
squareMatrixArgs <- list('double(2, c(2, 2))', 'double(2, c(5, 5))')
squareMatrixArgs2 <- list('double(2)')
# To-Do: run with atomics on and off.
squareMatrixOps <- c(nimble:::matrixSquareOperators,
nimble:::matrixSquareReductionOperators)
squareMatrixOps <- setdiff(squareMatrixOps, 'trace') # remove trace. It shouldn't be there
squareMatrixOpTests <- make_AD_test_batch(
squareMatrixOps, squareMatrixArgs
)
modify_on_match(
squareMatrixOpTests, 'chol .+', 'input_gen_funs',
gen_pos_def_matrix ## see AD_test_utils.R
)
squareMatrixOpTests2a <- make_AD_test_batch(squareMatrixOps, squareMatrixArgs2, maker = make_AD_test2)
modify_on_match(squareMatrixOpTests2a, '', 'size', c(2, 2)) ## see AD_test_utils.R
modify_on_match(squareMatrixOpTests2a, 'chol .+', 'input_gen_funs', function(x) gen_pos_def_matrix(x))
modify_on_match(squareMatrixOpTests2a, 'logdet .+', 'input_gen_funs', function(x) gen_pos_def_matrix(x))
squareMatrixOpTests2b <- make_AD_test_batch(squareMatrixOps, squareMatrixArgs2, maker = make_AD_test2)
modify_on_match(squareMatrixOpTests2b, '', 'size', c(5, 5)) ## see AD_test_utils.R
modify_on_match(squareMatrixOpTests2b, 'chol .+', 'input_gen_funs', function(x) gen_pos_def_matrix(x))
modify_on_match(squareMatrixOpTests2b, 'logdet .+', 'input_gen_funs', function(x) gen_pos_def_matrix(x))
squareMatrixOpTests2 <- c(squareMatrixOpTests2a, squareMatrixOpTests2b)
squareMatrixOpTests2 <- squareMatrixOpTests2[-8] # logdet is hard to set up so it is hand-coded as logdet_test in test-ADfunctions
squareMatrixOpTests2 <- squareMatrixOpTests2[-5] # Chol test is hard to set up so it is hand-coded as wish_chol_test_log in test-ADfunctions
# modify_on_match after c() would fail because only the first of redundant names would get handled
# ADtestEnv$RCrelTol <- c(1e-12, 1e-4, 1e-2)
##lapply(squareMatrixOpTests2, test_AD2)
##debug(test_AD2)
##lapply(squareMatrixOpTests2[6], test_AD2) # Chol 5x5 can have some crazy unstable 2nd derivs.
# Hessian of det is numerically nearly zero in different ways - comparison disaster
# This affects log det too
# We evidently don't really support trace?
## ## compilation failures
## modify_on_match(
## squareMatrixOpTests, '(logdet|det) .+',
## 'knownFailures', list(compilation = TRUE)
## )
####################
## binary matrix ops
####################
# Note this is only matrix multiplication and there is a more thorough test-ADmatMult
binaryMatrixOps <- nimble:::matrixMultOperators
binaryMatrixArgs <- as.list(
data.frame(t(expand.grid(
c('double(2, c(3, 4))', 'double(2, c(4, 4))', 'double(2, c(1, 4))'),
c('double(2, c(4, 3))', 'double(2, c(4, 4))', 'double(2, c(4, 1))'))),
stringsAsFactors=FALSE)
)
# We don't make a binaryMatrixArgs2 because we want the different shaped built in as in binaryMatrixArgs
## binaryMatrixOpTests <- make_AD_test_batch(
## binaryMatrixOps, binaryMatrixArgs2
## )
binaryMatrixOpTests2 <- make_AD_test_batch(
binaryMatrixOps, binaryMatrixArgs, maker = make_AD_test2
)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.