Relative Error When Appropriate, Absolute Otherwise
relErr.RdrelErrV():Compute the signed relative error componentwise (“vectorized”) between the
targetandcurrentvectors, using the absolute error, i.e., the difference in case the relative error is not well defined, i.e., whentargetis zero or infinite.relErr():simply the mean absolute value of the relative errors between
targetandcurrentvectors; typically the “same” asall.equal.numeric(target, vector, tolerance=0, countEQ=TRUE).Currently useful only when both vectors are finite.
Arguments
- target
numeric, possibly scalar.
- current
numeric vector of
length()a multiple oflength(target); if anarray(inclmatrix), dimensions are preserved; for vectors,names(target)are preserved.- eps0
non-negative number; values
abs(target) < eps0should be treated as zero (and hence absolute instead of relative error be computed). This may be crucial whentargetis an"mpfr"-number vector.
Value
relErrV():a numeric vector of the same length (or array of the same dimension) as
current.
% target can be scalar
relErr():a single number.
Author
Martin Maechler,
originally as part of 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
#> target current absE relE
#> [1,] -1 -1e+00 0e+00 0.00e+00
#> [2,] 0 0e+00 0e+00 0.00e+00
#> [3,] 1 1e+00 0e+00 0.00e+00
#> [4,] 0 1e-07 1e-07 1.00e-07
#> [5,] 0 NaN NaN NaN
#> [6,] NA NA NA NA
#> [7,] NaN 0e+00 NaN NaN
#> [8,] Inf Inf NaN 0.00e+00
#> [9,] -Inf Inf Inf Inf
#> [10,] Inf 0e+00 -Inf -Inf
#> [11,] 0 Inf Inf Inf
#> [12,] Inf 1e+00 -Inf -Inf
#> [13,] 1 Inf Inf Inf
#> [14,] -3 -3e+00 -9e-04 3.00e-04
#> [15,] -2 -2e+00 -8e-04 4.00e-04
#> [16,] -1 -1e+00 -6e-04 6.00e-04
#> [17,] 0 -4e-04 -4e-04 -4.00e-04
#> [18,] 1 1e+00 5e-05 5.00e-05
#> [19,] 2 2e+00 1e-04 5.00e-05
#> [20,] 3 3e+00 5e-04 1.67e-04
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
#> Asserted error: length(current) == 0 differing from length(target)
## relErr() is pretty simple --- (possibly too simple, currently)
relErr
#> function (target, current)
#> {
#> n <- length(current)
#> if (length(target) < n)
#> target <- rep(target, length.out = n)
#> sum(abs(target - current))/sum(abs(target))
#> }
#> <bytecode: 0x5ec1bd55dfd8>
#> <environment: namespace:sfsmisc>
relErr(target, current) # NA (of course)
#> [1] NA
all.equal.numeric(target, current) ## "'is.NA' value mismatch ..."
#> [1] "'is.NA' value mismatch: 2 in current 2 in target"
## comparison after dropping NA's :
hasN <- is.na(target) | is.na(current)
all.equal(target[!hasN], current[!hasN], tolerance=0) # "Mean abs. diff.: Inf"
#> [1] "Mean absolute difference: Inf"
relErr(target[!hasN], current[!hasN]) # NaN (to improve?)
#> [1] NaN
## 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.."
#> [1] "Mean relative difference: 0.000279"
all.equal(target[finN], current[finN], tol=0, countEQ=TRUE) # " " : 0.000239..
#> [1] "Mean relative difference: 0.000193"
relErr(target[finN], current[finN]) # 0.0002392929
#> [1] 0.000239