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+ cmp <- .Generic %in% c(" ==" , " !=" , " <" , " >" , " <=" , " >=" ) # comparison-type
30+ pm <- .Generic %in% c(" +" , " -" ) # addition-type
31+ prd <- .Generic %in% c(" *" , " /" , " %/%" , " %%" ) # product-type
32+ pw <- .Generic %in% c(" **" , " ^" ) # power-type
33+
34+ if (! any(cmp , pm , prd , pw ))
35+ stop(paste(" operation" , .Generic , " not allowed" ))
36+
37+ if (cmp && ! getOption(" errors.compare.probabilistic" , default = FALSE ))
2338 return (NextMethod())
24- }
2539
2640 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- }
41+ if (! inherits(e1 , " errors" )) e1 <- set_errors(e1 )
42+ if (! inherits(e2 , " errors" )) e2 <- set_errors(e2 )
3243 }
3344
3445 deriv <- switch (
3546 .Generic ,
47+
48+ # comparison-type
49+ " ==" = return (NextMethod() & ((! .e(e1 ) & ! .e(e2 )) | .c(e1 , e2 ) == 1 )),
50+ " !=" = return (NextMethod() | (( .e(e1 ) | .e(e2 )) & .c(e1 , e2 ) != 1 )),
51+ " <" = , " <=" = return (zstd(e2 - e1 , .Generic )),
52+ " >" = , " >=" = return (zstd(e1 - e2 , .Generic )),
53+
54+ # addition-type
3655 " +" = , " -" =
3756 if (missing(e2 )) {
3857 e2 <- NA
3958 list (do.call(.Generic , list (1 )), NA )
4059 }
4160 else list (1 , do.call(.Generic , list (1 ))),
61+
62+ # product-type
4263 " *" = list (.v(e2 ), .v(e1 )),
4364 " /" = list (1 / .v(e2 ), - .v(e1 ) / .v(e2 )^ 2 ),
4465 " %/%" = return (round(e1 / e2 )),
4566 " %%" = return (e1 - round(e1 / e2 ) * e2 ),
46- " ^" = list (.v(e1 )^ (.v(e2 )- 1 ) * .v(e2 ), .v(e1 )^ .v(e2 ) * log(abs(.v(e1 ))))
67+
68+ # power-type
69+ " **" = , " ^" =
70+ list (.v(e1 )^ (.v(e2 )- 1 ) * .v(e2 ), .v(e1 )^ .v(e2 ) * log(abs(.v(e1 ))))
4771 )
72+
4873 propagate(unclass(NextMethod()), e1 , e2 , deriv [[1 ]], deriv [[2 ]])
4974}
5075
@@ -61,10 +86,6 @@ Ops.errors <- function(e1, e2) {
6186# '
6287# ' #' @export
6388# ' `%*%.errors` = function(x, y) {
64- # ' warn_once(
65- # ' "matrix multiplication not supported for 'errors' objects, uncertainty dropped",
66- # ' fun = .Generic,
67- # ' type = "matmult"
68- # ' )
89+ # ' warning("matrix multiplication not supported for 'errors' objects, uncertainty dropped")
6990# ' base::`%*%`(unclass(x), unclass(y))
7091# ' }
0 commit comments