[Rd] compairing doubles

Iñaki Ucar iuc@r @ending from fedor@project@org
Fri Aug 31 16:13:43 CEST 2018


El vie., 31 ago. 2018 a las 16:00, Mark van der Loo
(<mark.vanderloo using gmail.com>) escribió:
>
> how about
>
> is_evenly_spaced <- function(x,...) all.equal(diff(sort(x)),...)

This doesn't work, because

1. all.equal does *not* return FALSE. Use of isTRUE or identical(.,
TRUE) is required if you want a boolean.
2. all.equal compares two objects, not elements in a vector.

Iñaki

>
> (use ellipsis to set tolerance if necessary)
>
>
> Op vr 31 aug. 2018 om 15:46 schreef Emil Bode <emil.bode using dans.knaw.nl>:
>>
>> Agreed that's it's rounding error, and all.equal would be the way to go.
>> I wouldn't call it a bug, it's simply part of working with floating point numbers, any language has the same issue.
>>
>> And while we're at it, I think the function can be a lot shorter:
>> .is_continous_evenly_spaced <- function(n){
>>   length(n)>1 && isTRUE(all.equal(n[order(n)], seq(from=min(n), to=max(n), length.out = length(n))))
>> }
>>
>> Cheers, Emil
>>
>>     El vie., 31 ago. 2018 a las 15:10, Felix Ernst
>>     (<felix.gm.ernst using outlook.com>) escribió:
>>     >
>>     > Dear all,
>>     >
>>     > I a bit unsure, whether this qualifies as a bug, but it is definitly a strange behaviour. That why I wanted to discuss it.
>>     >
>>     > With the following function, I want to test for evenly space numbers, starting from anywhere.
>>     >
>>     > .is_continous_evenly_spaced <- function(n){
>>     >   if(length(n) < 2) return(FALSE)
>>     >   n <- n[order(n)]
>>     >   n <- n - min(n)
>>     >   step <- n[2] - n[1]
>>     >   test <- seq(from = min(n), to = max(n), by = step)
>>     >   if(length(n) == length(test) &&
>>     >      all(n == test)){
>>     >     return(TRUE)
>>     >   }
>>     >   return(FALSE)
>>     > }
>>     >
>>     > > .is_continous_evenly_spaced(c(1,2,3,4))
>>     > [1] TRUE
>>     > > .is_continous_evenly_spaced(c(1,3,4,5))
>>     > [1] FALSE
>>     > > .is_continous_evenly_spaced(c(1,1.1,1.2,1.3))
>>     > [1] FALSE
>>     >
>>     > I expect the result for 1 and 2, but not for 3. Upon Investigation it turns out, that n == test is TRUE for every pair, but not for the pair of 0.2.
>>     >
>>     > The types reported are always double, however n[2] == 0.1 reports FALSE as well.
>>     >
>>     > The whole problem is solved by switching from all(n == test) to all(as.character(n) == as.character(test)). However that is weird, isn’t it?
>>     >
>>     > Does this work as intended? Thanks for any help, advise and suggestions in advance.
>>
>>     I guess this has something to do with how the sequence is built and
>>     the inherent error of floating point arithmetic. In fact, if you
>>     return test minus n, you'll get:
>>
>>     [1] 0.000000e+00 0.000000e+00 2.220446e-16 0.000000e+00
>>
>>     and the error gets bigger when you continue the sequence; e.g., this
>>     is for c(1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7):
>>
>>     [1] 0.000000e+00 0.000000e+00 2.220446e-16 2.220446e-16 4.440892e-16
>>     [6] 4.440892e-16 4.440892e-16 0.000000e+00
>>
>>     So, independently of this is considered a bug or not, instead of
>>
>>     length(n) == length(test) && all(n == test)
>>
>>     I would use the following condition:
>>
>>     isTRUE(all.equal(n, test))
>>
>>     Iñaki
>>
>>     >
>>     > Best regards,
>>     > Felix
>>     >
>>     >
>>     >         [[alternative HTML version deleted]]
>>     >
>>     > ______________________________________________
>>     > R-devel using r-project.org mailing list
>>     > https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>>
>>     --
>>     Iñaki Ucar
>>
>>     ______________________________________________
>>     R-devel using r-project.org mailing list
>>     https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>> ______________________________________________
>> R-devel using r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel



-- 
Iñaki Ucar



More information about the R-devel mailing list