El vie., 31 ago. 2018 a las 16:00, Mark van der Loo (<mark.vanderloo at 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 at 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 at 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 at r-project.org mailing list >> > https://stat.ethz.ch/mailman/listinfo/r-devel >> >> >> >> -- >> I?aki Ucar >> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel-- I?aki Ucar
Ah, my bad, you're right of course. sum(abs(diff(diff( sort(x))))) < eps for some reasonable eps then, would do as a oneliner, or all(abs(diff(diff(sort(x)))) < eps) or max(abs(diff(diff(sort(x))))) < eps -Mark Op vr 31 aug. 2018 om 16:14 schreef I?aki Ucar <iucar at fedoraproject.org>:> El vie., 31 ago. 2018 a las 16:00, Mark van der Loo > (<mark.vanderloo at 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 at 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 at 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 at r-project.org mailing list > >> > https://stat.ethz.ch/mailman/listinfo/r-devel > >> > >> > >> > >> -- > >> I?aki Ucar > >> > >> ______________________________________________ > >> R-devel at r-project.org mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-devel > >> > >> > >> ______________________________________________ > >> R-devel at r-project.org mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-devel > > > > -- > I?aki Ucar >[[alternative HTML version deleted]]
Le 31/08/2018 ? 16:25, Mark van der Loo a ?crit?:> Ah, my bad, you're right of course. > > sum(abs(diff(diff( sort(x))))) < eps > > for some reasonable eps then, would do as a oneliner, or > > all(abs(diff(diff(sort(x)))) < eps) > > or > > max(abs(diff(diff(sort(x))))) < epsOr with only four function calls: diff(range(diff(sort(x)))) < eps Serguei.> > > -Mark > > Op vr 31 aug. 2018 om 16:14 schreef I?aki Ucar <iucar at fedoraproject.org>: > >> El vie., 31 ago. 2018 a las 16:00, Mark van der Loo >> (<mark.vanderloo at 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 at 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 at 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 at r-project.org mailing list >>>> > https://stat.ethz.ch/mailman/listinfo/r-devel >>>> >>>> >>>> >>>> -- >>>> I?aki Ucar >>>> >>>> ______________________________________________ >>>> R-devel at r-project.org mailing list >>>> https://stat.ethz.ch/mailman/listinfo/r-devel >>>> >>>> >>>> ______________________________________________ >>>> R-devel at r-project.org mailing list >>>> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> >> -- >> I?aki Ucar >> > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- Serguei Sokol Ingenieur de recherche INRA Cellule math?matiques LISBP, INSA/INRA UMR 792, INSA/CNRS UMR 5504 135 Avenue de Rangueil 31077 Toulouse Cedex 04 tel: +33 5 62 25 01 27 email: sokol at insa-toulouse.fr http://www.lisbp.fr