# R/regtest.R In regtest: Regression testing

#source("d:/MWP/eAnalysis/regtest/R/regtest.R")

#! \name{timefactor}
#! \alias{timefactor}
#! \title{ compare timing of two expressions }
#! \description{
#!   Compare timings of two expressions, expressions that do not take enough time to be measured can be repeated often enough to be measured.
#! }
#! \usage{
#! timefactor(nom, denom, repnom = 1, repdenom = 1)
#! }
#! \arguments{
#!   \item{nom}{ nominator expression }
#!   \item{denom}{ denominator expression }
#!   \item{repnom}{ no. of repetitions of nominator }
#!   \item{repdenom}{ no. of repetitions of denominator }
#! }
#! \value{
#!   matrix with absolzute and relative timings
#! }
#! \author{ Jens Oehlschlägel }
#! \examples{
#!   timefactor(Sys.sleep(0.1), Sys.sleep(1), 10, 1)
#! }
#! \keyword{ misc }

timefactor <-
function (nom, denom, repnom = 1, repdenom = 1)
{
gc()
n <- system.time(for (f in 1:repnom) eval(substitute(nom), envir=parent.frame()))
d <- system.time(for (f in 1:repdenom) eval(substitute(denom), envir=parent.frame()))
cbind(nom = n/repnom, denom = d/repdenom, factor = repdenom/repnom *
n/d)[c(1:3), ]
}

#! \name{is.all.equal}
#! \alias{is.all.equal}
#! \title{ wrapper for all.equal }
#! \description{
#!   like all.equal but always returns logical
#! }
#! \usage{
#! is.all.equal(a, b, \dots)
#! }
#! \arguments{
#!   \item{a}{ expression to compare }
#!   \item{b}{ expression to compare }
#!   \item{\dots}{ further arguments to \code{\link{all.equal}} }
#! }
#! \value{ TRUE or FALSE }
#! \author{ Jens Oehlschlägel }
#! \examples{
#!   all.equal(1,2)
#!   is.all.equal(1,2)
#! }
#! \keyword{ debugging }
#! \keyword{ utilities }

is.all.equal <- function(a, b, ...){
x <- all.equal(a,b,...)
is.logical(x) && x
}

#! \name{binregtest}
#! \alias{binregtest}
#! \title{ Binary regression test }
#! \description{
#!   This function compares to parallel implementations of the same function for equality with respect to all (defined) parameter combinations.
#! }
#! \usage{
#! binregtest(FUN1, FUN2, ..., PARS = NULL, PAR1 = NULL, PAR2 = NULL, WHICH = sample(1:n), TRYALL = TRUE, COMP = is.all.equal, NAME = "UNNAMED binregtest", VERBOSE = FALSE)
#! }
#! \arguments{
#!   \item{FUN1}{ first function }
#!   \item{FUN2}{ second function }
#!   \item{\dots}{ common arguments, each specified as a list }
#!   \item{PARS}{ list of common arguments, each specified as a list, helps to use argument names that are used by \code{binregtest} itself}
#!   \item{PAR1}{ optional parameters only handed over to FUN1 (default NULL) }
#!   \item{PAR2}{ optional parameters only handed over to FUN2 (default NULL) }
#!   \item{WHICH}{ optional integer vector defining a subset of the possible parameter combinations }
#!   \item{TRYALL}{ FALSE to interrupt testing once an error has been found (default TRUE tests everything) }
#!   \item{COMP}{ function to compare results (default \code{\link{is.all.equal}}) }
#!   \item{NAME}{ character scalar describing this regression test }
#!   \item{VERBOSE}{ TRUE to verbose all tests (default FALSE) }
#! }
#! \value{
#!   TRUE if all tests were successful, FALSE otherwise
#! }
#! \author{ Jens Oehlschlägel }
#! \examples{
#! wronglog <- function(x, base=exp(1)){
#!   if (x>0)
#!     log(x, base=base)
#!   else
#!     NA
#! }
#! binregtest(wronglog, log, x=as.list(0:3), base=list(2, exp(1), 10))
#! }
#! \keyword{ debugging }
#! \keyword{ documentation }

binregtest <- function(
FUN1
, FUN2
, ...
, PARS  = NULL
, PAR1  = NULL
, PAR2  = NULL
, WHICH = sample(1:n)
, TRYALL= TRUE
, COMP  = is.all.equal
, NAME  = "UNNAMED binregtest"
, VERBOSE = FALSE
){
FUN1NAME <- deparse(substitute(FUN1))
FUN2NAME <- deparse(substitute(FUN2))
PAR1NAME <- deparse(substitute(PAR1))
PAR2NAME <- deparse(substitute(PAR2))
all(sapply(list(...), is.list))
all(sapply(PARS, is.list))
PARS <- c(list(...), PARS)
np <- length(PARS)
ip <- as.integer(seq(np))
names(ip) <- names(PARS)
N <- sapply(PARS, length)
n <- rev(cumprod(N))[1]
L <- lapply(PARS, function(i)as.integer(seq(along=i)))
success <- TRUE
d <- do.call("expand.grid", c(L, list(KEEP.OUT.ATTRS = FALSE)))
for (i in WHICH){
di <- d[i,,drop=TRUE]
P <- lapply(ip, function(j){
PARS[[j]][[di[[j]]]]
})
if (VERBOSE){
cat("\n\nVERBOSEing ", NAME," ", i, " of ", length(WHICH),"\n", sep="")
str(FUN1)
str(PAR1)
str(FUN2)
str(PAR2)
str(P)
}
str
for (j in rev(ip))
if (identical(P[[j]], missing))
P[[j]] <- NULL
seed <- as.integer(runif(1, min=0, max=.Machine\$integer.max))
set.seed(seed)
RET1 <- try(do.call("FUN1", c(PAR1, P)))
set.seed(seed)
RET2 <- try(do.call("FUN2", c(PAR2, P)))
this.success <- TRUE
if (inherits(RET1, "try-error")){
this.success <- FALSE
cat("\n\n",NAME,"\n",sep="")
cat("error in FUN1", FUN1NAME, "PAR1", PAR1NAME, "\n")
str(FUN1)
str(PAR1)
}
if (inherits(RET2, "try-error")){
this.success <- FALSE
cat("\n\n",NAME,"\n",sep="")
cat("error in FUN2", FUN2NAME, "PAR2", PAR2NAME, "\n")
str(FUN2)
str(PAR2)
}
if (!this.success){
cat("common PARS\n")
str(P)
}else{
if (!COMP(RET1, RET2)){
this.success <- FALSE
cat("\n\n",NAME,"\n",sep="")
cat("difference between FUN1", FUN1NAME, "PAR1", PAR1NAME, "and FUN2", FUN2NAME, "PAR2", PAR2NAME, "\n")
str(FUN1)
str(PAR1)
str(FUN2)
str(PAR2)
cat("common PARS\n")
str(P)
cat("RET1\n")
str(RET1)
cat("RET2\n")
str(RET2)
}
}
success <- success && this.success
if (!this.success && !TRYALL)
break
}
success
}


## Try the regtest package in your browser

Any scripts or data that you put into this service are public.

regtest documentation built on May 2, 2019, 5:57 a.m.