Relative Error When Appropriate, Absolute Otherwise
Relative Error When Appropriate, Absolute Otherwise
relErrV():: Compute the signed relative error componentwise (vectorized ) between the target and current vectors, using the absolute error, i.e., the difference in case the relative error is not well defined, i.e., when target
is zero or infinite.
relErr():: simply the mean absolute value of the relative errors between target and current vectors; typically the same as all.equal.numeric(target, vector, tolerance=0, countEQ=TRUE).
Currently useful only when both vectors are finite.
current: numeric vector of length() a multiple of length(target); if an array (incl matrix), dimensions are preserved; for vectors, names(target) are preserved.
eps0: non-negative number; values abs(target) < eps0 should be treated as zero (and hence absolute instead of relative error be computed). This may be crucial when target is an "mpfr"-number vector.
Returns
relErrV():: a numeric vector of the same length (or array of the same dimension) as current.
relErr():: a single number.
Author(s)
Martin Maechler, originally as part of list("Matrix") package's test-tools.R .
See Also
all.equal.numeric() is similar in spirit but returns TRUE or string containing the mean relative or absolute error.
Examples
## relErrV() test example: showing how it works fine with {NA, Inf, 0} :eps <-1e-4*c(-9,-8,-6,-4,0.5,1,5)target <- c(-1:1,0,0,NA,NaN,Inf,-Inf,Inf,0,Inf,1,-3:3)current <- c(-1:1,1e-7,NaN,NA,0,Inf,Inf,0,Inf,1,Inf,-3:3+ eps)cbind(target, current, absE = current-target, relE = relErrV(target,current))-> M ; M
stopifnot(exprs ={ is.logical(isFr <- is.finite(rF <- M[,"relE"])) target==current | isFr == is.finite(aF <- M[,"absE"]) identical(aF[!isFr], rF[!isFr]) identical(numeric(), relErrV(numeric(), integer()))# length 0 {used to fail}})tools::assertError(relErrV(1, numeric()), verbose=TRUE)# no longer allowed## relErr() is pretty simple --- (possibly too simple, currently)relErr
relErr(target, current)# NA (of course)all.equal.numeric(target, current)## "'is.NA' value mismatch ..."## comparison after dropping NA's :hasN <- is.na(target)| is.na(current)all.equal(target[!hasN], current[!hasN], tolerance=0)# "Mean abs. diff.: Inf" relErr(target[!hasN], current[!hasN])# NaN (to improve?)## comparison after only keeping cases where both are finite:finN <- is.finite(target)& is.finite(current)all.equal(target[finN], current[finN], tol=0)# "Mean abs.d.: 0.000279.."all.equal(target[finN], current[finN], tol=0, countEQ=TRUE)# " " : 0.000239.. relErr(target[finN], current[finN])# 0.0002392929