11# ' @rdname groupGeneric.errors
22# '
33# ' @details \subsection{\code{Ops}}{
4- # ' Boolean operators drop the uncertainty (showing a warning once) and operate on the
5- # ' numeric values. The rest of the operators propagate the uncertainty as expected from
4+ # ' Boolean operators drop the uncertainty and operate on the numeric values
5+ # ' unless the option \code{errors.compare.probabilistic} is set to \code{TRUE}.
6+ # ' In such case the comparison operators return a numeric value between 0 and 1,
7+ # ' representing the probability that the comparison is true, assuming normal
8+ # ' distribution of the errors.
9+ # ' The rest of the operators propagate the uncertainty as expected from
610# ' the first-order Taylor series method. Any numeric operand is automatically
7- # ' coerced to \code{errors} (showing a warning once) with no uncertainty.}
11+ # ' coerced to \code{errors} with no uncertainty.}
812# '
913# ' @examples
10- # ' y <- set_errors(4:6, 0.2 )
14+ # ' y <- set_errors(1:3 + 0.1, c(0, 0.1, 0.2) )
1115# ' x / sqrt(y) + y * sin(x)
1216# '
1317# ' # numeric values are automatically coerced to errors
1418# ' x^2
1519# '
1620# ' # boolean operators drop uncertainty
1721# ' y > x
22+ # ' # unless probabilistic comparisons are enabled
23+ # ' options(errors.compare.probabilistic = TRUE)
24+ # ' y > x
25+ # ' options(errors.compare.probabilistic = NULL)
1826# '
1927# ' @export
2028Ops.errors <- function (e1 , e2 ) {
21- if (.Generic %in% c(" &" , " |" , " !" , " ==" , " !=" , " <" , " >" , " <=" , " >=" )) {
22- warn_once_bool(.Generic )
29+ if (.Generic == " !" )
30+ return (NextMethod())
31+
32+ cmp <- .Generic %in% c(" ==" , " !=" , " <" , " >" , " <=" , " >=" ) # comparison-type
33+ pm <- .Generic %in% c(" +" , " -" ) # addition-type
34+ prd <- .Generic %in% c(" *" , " /" , " %/%" , " %%" ) # product-type
35+ pw <- .Generic %in% c(" **" , " ^" ) # power-type
36+
37+ if (! any(cmp , pm , prd , pw ))
38+ stop(paste(" operation" , .Generic , " not allowed" ))
39+
40+ if (cmp && ! getOption(" errors.compare.probabilistic" , default = FALSE ))
2341 return (NextMethod())
24- }
2542
2643 if (! missing(e2 )) {
27- coercion <- cond2int(! inherits(e1 , " errors" ), ! inherits(e2 , " errors" ))
28- if (coercion ) {
29- warn_once_coercion(" Ops" )
30- switch (coercion , e1 <- set_errors(e1 ), e2 <- set_errors(e2 ))
31- }
44+ if (! inherits(e1 , " errors" )) e1 <- set_errors(e1 )
45+ if (! inherits(e2 , " errors" )) e2 <- set_errors(e2 )
3246 }
3347
3448 deriv <- switch (
3549 .Generic ,
50+
51+ # comparison-type
52+ " ==" = return (NextMethod() & ((! .e(e1 ) & ! .e(e2 )) | .c(e1 , e2 ) == 1 )),
53+ " !=" = return (NextMethod() | (( .e(e1 ) | .e(e2 )) & .c(e1 , e2 ) != 1 )),
54+ " <" = , " <=" = return (zstd(e2 - e1 , .Generic )),
55+ " >" = , " >=" = return (zstd(e1 - e2 , .Generic )),
56+
57+ # addition-type
3658 " +" = , " -" =
3759 if (missing(e2 )) {
3860 e2 <- NA
3961 list (do.call(.Generic , list (1 )), NA )
4062 }
4163 else list (1 , do.call(.Generic , list (1 ))),
64+
65+ # product-type
4266 " *" = list (.v(e2 ), .v(e1 )),
4367 " /" = list (1 / .v(e2 ), - .v(e1 ) / .v(e2 )^ 2 ),
4468 " %/%" = return (round(e1 / e2 )),
4569 " %%" = return (e1 - round(e1 / e2 ) * e2 ),
46- " ^" = list (.v(e1 )^ (.v(e2 )- 1 ) * .v(e2 ), .v(e1 )^ .v(e2 ) * log(abs(.v(e1 ))))
70+
71+ # power-type
72+ " **" = , " ^" =
73+ list (.v(e1 )^ (.v(e2 )- 1 ) * .v(e2 ), .v(e1 )^ .v(e2 ) * log(abs(.v(e1 ))))
4774 )
75+
4876 propagate(unclass(NextMethod()), e1 , e2 , deriv [[1 ]], deriv [[2 ]])
4977}
5078
@@ -61,10 +89,6 @@ Ops.errors <- function(e1, e2) {
6189# '
6290# ' #' @export
6391# ' `%*%.errors` = function(x, y) {
64- # ' warn_once(
65- # ' "matrix multiplication not supported for 'errors' objects, uncertainty dropped",
66- # ' fun = .Generic,
67- # ' type = "matmult"
68- # ' )
92+ # ' warning("matrix multiplication not supported for 'errors' objects, uncertainty dropped")
6993# ' base::`%*%`(unclass(x), unclass(y))
7094# ' }
0 commit comments