Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would one use this tolerance in is.wholenumber

Tags:

r

The help page for ?is.integer has a note about a function that will tell us if a value is an integer:

is.wholenumber <-
   function(x, tol = .Machine$double.eps^0.5)  abs(x - round(x)) < tol

What could be the argument to use sqrt(eps) as tolerance here? Also, is there a good reason to use anything else than tol=0?

The background is my answer on this question. Some commenters objected to this function.

My simple minded hypothesis: this is done to make it close in behavior to print (which has a default of 7 decimal digits). E.g.:

> 1.000005
[1] 1.000005
> 1.0000000005
[1] 1
> is.wholenumber(1.000005)
[1] FALSE
> is.wholenumber(1.0000000005)
[1] TRUE

It does not work perfectly though:

> 1.00000005
[1] 1
> is.wholenumber(1.00000005)
[1] FALSE

There is a better argument in the comments below: the sqrt(eps) may be a (rough) estimate of the round-off error caused by floating-point operations.

like image 768
Erwin Kalvelagen Avatar asked Mar 13 '16 15:03

Erwin Kalvelagen


1 Answers

Compare

> is.wholenumber(0.6/0.2, tol=0)
[1] FALSE
> is.wholenumber(0.6/0.2)
[1] TRUE

While 3 == 0.6/0.3 exactly in reality, it is not so in floating point representation.

From the helpfile for "=="

For numerical and complex values, remember ‘==’ and ‘!=’ do not allow for the finite representation of fractions, nor for rounding error. Using ‘all.equal’ with ‘identical’ is almost always preferable.

The default tolerance for is.wholenumber is set to the same amount as in all.equal:

 ## S3 method for class 'numeric'
 all.equal(target, current,
           tolerance = .Machine$double.eps ^ 0.5, scale = NULL,
           ..., check.attributes = TRUE)

This means that the default behavior of is.wholenumber is comparable to

isTRUE(all.equal(0,abs(x - round(x))))

To take our example full circle

> x <- 0.6/0.2
> x
[1] 3
> round(x)
[1] 3
> x == round(x)
[1] FALSE
> isTRUE(all.equal(0,x-round(x)))
[1] TRUE
> isTRUE(all.equal(0,x-round(x), tol=0))
[1] FALSE
like image 189
A. Webb Avatar answered Nov 15 '22 06:11

A. Webb