Dear All, This answer is very clear. Many thanks. I am now confused about how str*ucture works. Where can I read more about when does it return language / logical / chr ? I would want to read that so I can interpret the result of structure. I don't think ?str contains this.To me, logical and chr make sense, what does language mean? I think I need to read some more. Many thanks, Ashim On Tue, Apr 25, 2017 at 3:14 PM, Martin Maechler <maechler at stat.math.ethz.ch> wrote:> >>>>> Ashim Kapoor <ashimkapoor at gmail.com> > >>>>> on Tue, 25 Apr 2017 14:02:18 +0530 writes: > > > Dear all, > > I am not able to understand the interplay of absolute vs relative and > > tolerance in the use of all.equal > > > If I want to find out if absolute differences between 2 > numbers/vectors are > > bigger than a given tolerance I would do: > > > all.equal(1,1.1,scale=1,tol= .1) > > > If I want to find out if relative differences between 2 > numbers/vectors are > > bigger than a given tolerance I would do : > > > all.equal(1,1.1,tol=.1) > > > ############################################################ > ###################################################################### > > > I can also do : > > > all.equal(1,3,tol=1) > > > to find out if the absolute difference is bigger than 1.But here I > won't be > > able to detect absolute differences smaller than 1 in this case,so I > don't > > think that this is a good way. > > > My query is: what is the reasoning behind all.equal returning the > absolute > > difference if the tolerance >= target and relative difference if > tolerance > > < target? > (above, it is tol >/<= |target| ie. absolute value) > > > The following are desiderata / restrictions : > > 1) Relative tolerance is needed to keep things scale-invariant > i.e., all.equal(x, y) and all.equal(1000 * x, 1000 * y) > should typically be identical for (almost) all (x,y). > > ==> "the typical behavior should use relative error tolerance" > > 2) when x or y (and typically both!) are very close to zero it > is typically undesirable to keep relative tolerances (in the > boundary case, they _are_ zero exactly, and "relative error" is > undefined). > E.g., for most purposes, 3.45e-15 and 1.23e-17 should be counted as > equal to zero and hence to themselves. > > 1) and 2) are typically reconciled by switching from relative to absolute > when the arguments are close to zero (*). > > The exact cutoff at which to switch from relative to absolute > (or a combination of the two) is somewhat arbitrary(*2) and for > all.equal() has been made in the 1980's (or even slightly > earlier?) when all.equal() was introduced into the S language at > Bell labs AFAIK. Maybe John Chambers (or Rick Becker or ..., > but they may not read R-help) knows more. > *2) Then, the choice for all.equal() is in some way "least arbitrary", > using c = 1 in the more general tolerance >= c*|target| framework. > > *) There have been alternatives in "the (applied numerical > analysis / algorithm) literature" seen in published algorithms, > but I don't have any example ready. > Notably some of these alternatives are _symmetric_ in (x,y) > where all.equal() was designed to be asymmetric using names > 'target' and 'current'. > > The alternative idea is along the following thoughts: > > Assume that for "equality" we want _both_ relative and > absolute (e := tolerance) "equality" > > |x - y| < e (|x|+|y|)/2 (where you could use |y| or |x| > instead of their mean; all.equal() > uses |target|) > |x - y| < e * e1 (where e1 = 1, or e1 = 10^-7..) > > If you add the two inequalities you get > > |x - y| < e (e1 + |x+y|/2) > > as check which is a "mixture" of relative and absolute tolerance. > > With a somewhat long history, my gut feeling would nowadays > actually prefer this (I think with a default of e1 = e) - which > does treat x and y symmetrically. > > Note that convergence checks in good algorithms typically check > for _both_ relative and absolute difference (each with its > tolerance providable by the user), and the really good ones for > minimization do check for (approximate) gradients also being > close to zero - as old timers among us should have learned from > Doug Bates ... but now I'm really diverging. > > Last but not least some R code at the end, showing that the *asymmetric* > nature of all.equal() may lead to somewhat astonishing (but very > logical and as documented!) behavior. > > Martin > > > Best Regards, > > Ashim > > > > ## The "data" to use: > > epsQ <- lapply(seq(12,18,by=1/2), function(P) bquote(10^-.(P))); > names(epsQ) <- sapply(epsQ, deparse); str(epsQ) > List of 13 > $ 10^-12 : language 10^-12 > $ 10^-12.5: language 10^-12.5 > $ 10^-13 : language 10^-13 > $ 10^-13.5: language 10^-13.5 > $ 10^-14 : language 10^-14 > $ 10^-14.5: language 10^-14.5 > $ 10^-15 : language 10^-15 > $ 10^-15.5: language 10^-15.5 > $ 10^-16 : language 10^-16 > $ 10^-16.5: language 10^-16.5 > $ 10^-17 : language 10^-17 > $ 10^-17.5: language 10^-17.5 > $ 10^-18 : language 10^-18 > > > str(lapply(epsQ, function(tl) all.equal(3.45e-15, 1.23e-17, tol > eval(tl)))) > List of 13 > $ 10^-12 : logi TRUE > $ 10^-12.5: logi TRUE > $ 10^-13 : logi TRUE > $ 10^-13.5: logi TRUE > $ 10^-14 : logi TRUE > $ 10^-14.5: chr "Mean relative difference: 0.9964348" > $ 10^-15 : chr "Mean relative difference: 0.9964348" > $ 10^-15.5: chr "Mean relative difference: 0.9964348" > $ 10^-16 : chr "Mean relative difference: 0.9964348" > $ 10^-16.5: chr "Mean relative difference: 0.9964348" > $ 10^-17 : chr "Mean relative difference: 0.9964348" > $ 10^-17.5: chr "Mean relative difference: 0.9964348" > $ 10^-18 : chr "Mean relative difference: 0.9964348" > > > ## Now swap `target` and `current` : > > str(lapply(epsQ, function(tl) all.equal(1.23e-17, 3.45e-15, tol > eval(tl)))) > List of 13 > $ 10^-12 : logi TRUE > $ 10^-12.5: logi TRUE > $ 10^-13 : logi TRUE > $ 10^-13.5: logi TRUE > $ 10^-14 : logi TRUE > $ 10^-14.5: chr "Mean absolute difference: 3.4377e-15" > $ 10^-15 : chr "Mean absolute difference: 3.4377e-15" > $ 10^-15.5: chr "Mean absolute difference: 3.4377e-15" > $ 10^-16 : chr "Mean absolute difference: 3.4377e-15" > $ 10^-16.5: chr "Mean absolute difference: 3.4377e-15" > $ 10^-17 : chr "Mean relative difference: 279.4878" > $ 10^-17.5: chr "Mean relative difference: 279.4878" > $ 10^-18 : chr "Mean relative difference: 279.4878" > > > >[[alternative HTML version deleted]]
On 30/04/2017 12:26 PM, Ashim Kapoor wrote:> Dear All, > > This answer is very clear. Many thanks. > > I am now confused about how str*ucture works. Where can I read more about > when does it return language / logical / chr ? I would want to read that > so I can interpret the result of structure. I don't think ?str contains > this.To me, logical and chr make sense, what does language mean? I think I > need to read some more.I would read the R Language Definition manual, and then bits and pieces of R Internals, as necessary. These are both included with R. There are also books separate from R that talk about these things, but I don't know which to recommend. Duncan Murdoch> > Many thanks, > Ashim > > On Tue, Apr 25, 2017 at 3:14 PM, Martin Maechler <maechler at stat.math.ethz.ch >> wrote: > >>>>>>> Ashim Kapoor <ashimkapoor at gmail.com> >>>>>>> on Tue, 25 Apr 2017 14:02:18 +0530 writes: >> >> > Dear all, >> > I am not able to understand the interplay of absolute vs relative and >> > tolerance in the use of all.equal >> >> > If I want to find out if absolute differences between 2 >> numbers/vectors are >> > bigger than a given tolerance I would do: >> >> > all.equal(1,1.1,scale=1,tol= .1) >> >> > If I want to find out if relative differences between 2 >> numbers/vectors are >> > bigger than a given tolerance I would do : >> >> > all.equal(1,1.1,tol=.1) >> >> > ############################################################ >> ###################################################################### >> >> > I can also do : >> >> > all.equal(1,3,tol=1) >> >> > to find out if the absolute difference is bigger than 1.But here I >> won't be >> > able to detect absolute differences smaller than 1 in this case,so I >> don't >> > think that this is a good way. >> >> > My query is: what is the reasoning behind all.equal returning the >> absolute >> > difference if the tolerance >= target and relative difference if >> tolerance >> > < target? >> (above, it is tol >/<= |target| ie. absolute value) >> >> >> The following are desiderata / restrictions : >> >> 1) Relative tolerance is needed to keep things scale-invariant >> i.e., all.equal(x, y) and all.equal(1000 * x, 1000 * y) >> should typically be identical for (almost) all (x,y). >> >> ==> "the typical behavior should use relative error tolerance" >> >> 2) when x or y (and typically both!) are very close to zero it >> is typically undesirable to keep relative tolerances (in the >> boundary case, they _are_ zero exactly, and "relative error" is >> undefined). >> E.g., for most purposes, 3.45e-15 and 1.23e-17 should be counted as >> equal to zero and hence to themselves. >> >> 1) and 2) are typically reconciled by switching from relative to absolute >> when the arguments are close to zero (*). >> >> The exact cutoff at which to switch from relative to absolute >> (or a combination of the two) is somewhat arbitrary(*2) and for >> all.equal() has been made in the 1980's (or even slightly >> earlier?) when all.equal() was introduced into the S language at >> Bell labs AFAIK. Maybe John Chambers (or Rick Becker or ..., >> but they may not read R-help) knows more. >> *2) Then, the choice for all.equal() is in some way "least arbitrary", >> using c = 1 in the more general tolerance >= c*|target| framework. >> >> *) There have been alternatives in "the (applied numerical >> analysis / algorithm) literature" seen in published algorithms, >> but I don't have any example ready. >> Notably some of these alternatives are _symmetric_ in (x,y) >> where all.equal() was designed to be asymmetric using names >> 'target' and 'current'. >> >> The alternative idea is along the following thoughts: >> >> Assume that for "equality" we want _both_ relative and >> absolute (e := tolerance) "equality" >> >> |x - y| < e (|x|+|y|)/2 (where you could use |y| or |x| >> instead of their mean; all.equal() >> uses |target|) >> |x - y| < e * e1 (where e1 = 1, or e1 = 10^-7..) >> >> If you add the two inequalities you get >> >> |x - y| < e (e1 + |x+y|/2) >> >> as check which is a "mixture" of relative and absolute tolerance. >> >> With a somewhat long history, my gut feeling would nowadays >> actually prefer this (I think with a default of e1 = e) - which >> does treat x and y symmetrically. >> >> Note that convergence checks in good algorithms typically check >> for _both_ relative and absolute difference (each with its >> tolerance providable by the user), and the really good ones for >> minimization do check for (approximate) gradients also being >> close to zero - as old timers among us should have learned from >> Doug Bates ... but now I'm really diverging. >> >> Last but not least some R code at the end, showing that the *asymmetric* >> nature of all.equal() may lead to somewhat astonishing (but very >> logical and as documented!) behavior. >> >> Martin >> >> > Best Regards, >> > Ashim >> >> >>> ## The "data" to use: >>> epsQ <- lapply(seq(12,18,by=1/2), function(P) bquote(10^-.(P))); >> names(epsQ) <- sapply(epsQ, deparse); str(epsQ) >> List of 13 >> $ 10^-12 : language 10^-12 >> $ 10^-12.5: language 10^-12.5 >> $ 10^-13 : language 10^-13 >> $ 10^-13.5: language 10^-13.5 >> $ 10^-14 : language 10^-14 >> $ 10^-14.5: language 10^-14.5 >> $ 10^-15 : language 10^-15 >> $ 10^-15.5: language 10^-15.5 >> $ 10^-16 : language 10^-16 >> $ 10^-16.5: language 10^-16.5 >> $ 10^-17 : language 10^-17 >> $ 10^-17.5: language 10^-17.5 >> $ 10^-18 : language 10^-18 >> >>> str(lapply(epsQ, function(tl) all.equal(3.45e-15, 1.23e-17, tol >> eval(tl)))) >> List of 13 >> $ 10^-12 : logi TRUE >> $ 10^-12.5: logi TRUE >> $ 10^-13 : logi TRUE >> $ 10^-13.5: logi TRUE >> $ 10^-14 : logi TRUE >> $ 10^-14.5: chr "Mean relative difference: 0.9964348" >> $ 10^-15 : chr "Mean relative difference: 0.9964348" >> $ 10^-15.5: chr "Mean relative difference: 0.9964348" >> $ 10^-16 : chr "Mean relative difference: 0.9964348" >> $ 10^-16.5: chr "Mean relative difference: 0.9964348" >> $ 10^-17 : chr "Mean relative difference: 0.9964348" >> $ 10^-17.5: chr "Mean relative difference: 0.9964348" >> $ 10^-18 : chr "Mean relative difference: 0.9964348" >> >>> ## Now swap `target` and `current` : >>> str(lapply(epsQ, function(tl) all.equal(1.23e-17, 3.45e-15, tol >> eval(tl)))) >> List of 13 >> $ 10^-12 : logi TRUE >> $ 10^-12.5: logi TRUE >> $ 10^-13 : logi TRUE >> $ 10^-13.5: logi TRUE >> $ 10^-14 : logi TRUE >> $ 10^-14.5: chr "Mean absolute difference: 3.4377e-15" >> $ 10^-15 : chr "Mean absolute difference: 3.4377e-15" >> $ 10^-15.5: chr "Mean absolute difference: 3.4377e-15" >> $ 10^-16 : chr "Mean absolute difference: 3.4377e-15" >> $ 10^-16.5: chr "Mean absolute difference: 3.4377e-15" >> $ 10^-17 : chr "Mean relative difference: 279.4878" >> $ 10^-17.5: chr "Mean relative difference: 279.4878" >> $ 10^-18 : chr "Mean relative difference: 279.4878" >> >>> >> > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
... Some R tutorial recommendations can be found here: https://www.rstudio.com/online-learning/#R Hadley W.'s book might also be useful to you: http://adv-r.had.co.nz/ Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Sun, Apr 30, 2017 at 9:35 AM, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:> On 30/04/2017 12:26 PM, Ashim Kapoor wrote: >> >> Dear All, >> >> This answer is very clear. Many thanks. >> >> I am now confused about how str*ucture works. Where can I read more about >> when does it return language / logical / chr ? I would want to read that >> so I can interpret the result of structure. I don't think ?str contains >> this.To me, logical and chr make sense, what does language mean? I think I >> need to read some more. > > > I would read the R Language Definition manual, and then bits and pieces of R > Internals, as necessary. These are both included with R. There are also > books separate from R that talk about these things, but I don't know which > to recommend. > > Duncan Murdoch > > >> >> Many thanks, >> Ashim >> >> On Tue, Apr 25, 2017 at 3:14 PM, Martin Maechler >> <maechler at stat.math.ethz.ch >>> >>> wrote: >> >> >>>>>>>> Ashim Kapoor <ashimkapoor at gmail.com> >>>>>>>> on Tue, 25 Apr 2017 14:02:18 +0530 writes: >>> >>> >>> > Dear all, >>> > I am not able to understand the interplay of absolute vs relative >>> and >>> > tolerance in the use of all.equal >>> >>> > If I want to find out if absolute differences between 2 >>> numbers/vectors are >>> > bigger than a given tolerance I would do: >>> >>> > all.equal(1,1.1,scale=1,tol= .1) >>> >>> > If I want to find out if relative differences between 2 >>> numbers/vectors are >>> > bigger than a given tolerance I would do : >>> >>> > all.equal(1,1.1,tol=.1) >>> >>> > ############################################################ >>> ###################################################################### >>> >>> > I can also do : >>> >>> > all.equal(1,3,tol=1) >>> >>> > to find out if the absolute difference is bigger than 1.But here I >>> won't be >>> > able to detect absolute differences smaller than 1 in this case,so >>> I >>> don't >>> > think that this is a good way. >>> >>> > My query is: what is the reasoning behind all.equal returning the >>> absolute >>> > difference if the tolerance >= target and relative difference if >>> tolerance >>> > < target? >>> (above, it is tol >/<= |target| ie. absolute value) >>> >>> >>> The following are desiderata / restrictions : >>> >>> 1) Relative tolerance is needed to keep things scale-invariant >>> i.e., all.equal(x, y) and all.equal(1000 * x, 1000 * y) >>> should typically be identical for (almost) all (x,y). >>> >>> ==> "the typical behavior should use relative error tolerance" >>> >>> 2) when x or y (and typically both!) are very close to zero it >>> is typically undesirable to keep relative tolerances (in the >>> boundary case, they _are_ zero exactly, and "relative error" is >>> undefined). >>> E.g., for most purposes, 3.45e-15 and 1.23e-17 should be counted as >>> equal to zero and hence to themselves. >>> >>> 1) and 2) are typically reconciled by switching from relative to absolute >>> when the arguments are close to zero (*). >>> >>> The exact cutoff at which to switch from relative to absolute >>> (or a combination of the two) is somewhat arbitrary(*2) and for >>> all.equal() has been made in the 1980's (or even slightly >>> earlier?) when all.equal() was introduced into the S language at >>> Bell labs AFAIK. Maybe John Chambers (or Rick Becker or ..., >>> but they may not read R-help) knows more. >>> *2) Then, the choice for all.equal() is in some way "least arbitrary", >>> using c = 1 in the more general tolerance >= c*|target| framework. >>> >>> *) There have been alternatives in "the (applied numerical >>> analysis / algorithm) literature" seen in published algorithms, >>> but I don't have any example ready. >>> Notably some of these alternatives are _symmetric_ in (x,y) >>> where all.equal() was designed to be asymmetric using names >>> 'target' and 'current'. >>> >>> The alternative idea is along the following thoughts: >>> >>> Assume that for "equality" we want _both_ relative and >>> absolute (e := tolerance) "equality" >>> >>> |x - y| < e (|x|+|y|)/2 (where you could use |y| or |x| >>> instead of their mean; all.equal() >>> uses |target|) >>> |x - y| < e * e1 (where e1 = 1, or e1 = 10^-7..) >>> >>> If you add the two inequalities you get >>> >>> |x - y| < e (e1 + |x+y|/2) >>> >>> as check which is a "mixture" of relative and absolute tolerance. >>> >>> With a somewhat long history, my gut feeling would nowadays >>> actually prefer this (I think with a default of e1 = e) - which >>> does treat x and y symmetrically. >>> >>> Note that convergence checks in good algorithms typically check >>> for _both_ relative and absolute difference (each with its >>> tolerance providable by the user), and the really good ones for >>> minimization do check for (approximate) gradients also being >>> close to zero - as old timers among us should have learned from >>> Doug Bates ... but now I'm really diverging. >>> >>> Last but not least some R code at the end, showing that the >>> *asymmetric* >>> nature of all.equal() may lead to somewhat astonishing (but very >>> logical and as documented!) behavior. >>> >>> Martin >>> >>> > Best Regards, >>> > Ashim >>> >>> >>>> ## The "data" to use: >>>> epsQ <- lapply(seq(12,18,by=1/2), function(P) bquote(10^-.(P))); >>> >>> names(epsQ) <- sapply(epsQ, deparse); str(epsQ) >>> List of 13 >>> $ 10^-12 : language 10^-12 >>> $ 10^-12.5: language 10^-12.5 >>> $ 10^-13 : language 10^-13 >>> $ 10^-13.5: language 10^-13.5 >>> $ 10^-14 : language 10^-14 >>> $ 10^-14.5: language 10^-14.5 >>> $ 10^-15 : language 10^-15 >>> $ 10^-15.5: language 10^-15.5 >>> $ 10^-16 : language 10^-16 >>> $ 10^-16.5: language 10^-16.5 >>> $ 10^-17 : language 10^-17 >>> $ 10^-17.5: language 10^-17.5 >>> $ 10^-18 : language 10^-18 >>> >>>> str(lapply(epsQ, function(tl) all.equal(3.45e-15, 1.23e-17, tol >>> >>> eval(tl)))) >>> List of 13 >>> $ 10^-12 : logi TRUE >>> $ 10^-12.5: logi TRUE >>> $ 10^-13 : logi TRUE >>> $ 10^-13.5: logi TRUE >>> $ 10^-14 : logi TRUE >>> $ 10^-14.5: chr "Mean relative difference: 0.9964348" >>> $ 10^-15 : chr "Mean relative difference: 0.9964348" >>> $ 10^-15.5: chr "Mean relative difference: 0.9964348" >>> $ 10^-16 : chr "Mean relative difference: 0.9964348" >>> $ 10^-16.5: chr "Mean relative difference: 0.9964348" >>> $ 10^-17 : chr "Mean relative difference: 0.9964348" >>> $ 10^-17.5: chr "Mean relative difference: 0.9964348" >>> $ 10^-18 : chr "Mean relative difference: 0.9964348" >>> >>>> ## Now swap `target` and `current` : >>>> str(lapply(epsQ, function(tl) all.equal(1.23e-17, 3.45e-15, tol >>> >>> eval(tl)))) >>> List of 13 >>> $ 10^-12 : logi TRUE >>> $ 10^-12.5: logi TRUE >>> $ 10^-13 : logi TRUE >>> $ 10^-13.5: logi TRUE >>> $ 10^-14 : logi TRUE >>> $ 10^-14.5: chr "Mean absolute difference: 3.4377e-15" >>> $ 10^-15 : chr "Mean absolute difference: 3.4377e-15" >>> $ 10^-15.5: chr "Mean absolute difference: 3.4377e-15" >>> $ 10^-16 : chr "Mean absolute difference: 3.4377e-15" >>> $ 10^-16.5: chr "Mean absolute difference: 3.4377e-15" >>> $ 10^-17 : chr "Mean relative difference: 279.4878" >>> $ 10^-17.5: chr "Mean relative difference: 279.4878" >>> $ 10^-18 : chr "Mean relative difference: 279.4878" >>> >>>> >>> >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide >> http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. >> > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
On Sun, Apr 30, 2017 at 10:05 PM, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:> On 30/04/2017 12:26 PM, Ashim Kapoor wrote: > >> Dear All, >> >> This answer is very clear. Many thanks. >> >> I am now confused about how str*ucture works. Where can I read more about >> when does it return language / logical / chr ? I would want to read that >> so I can interpret the result of structure. I don't think ?str contains >> this.To me, logical and chr make sense, what does language mean? I think I >> need to read some more. >> > > I would read the R Language Definition manual, and then bits and pieces of > R Internals, as necessary. These are both included with R. There are also > books separate from R that talk about these things, but I don't know which > to recommend. > > Can you please name those books ?> Duncan Murdoch > > >> Many thanks, >> Ashim >> >> On Tue, Apr 25, 2017 at 3:14 PM, Martin Maechler < >> maechler at stat.math.ethz.ch >> >>> wrote: >>> >> >> Ashim Kapoor <ashimkapoor at gmail.com> >>>>>>>> on Tue, 25 Apr 2017 14:02:18 +0530 writes: >>>>>>>> >>>>>>> >>> > Dear all, >>> > I am not able to understand the interplay of absolute vs relative >>> and >>> > tolerance in the use of all.equal >>> >>> > If I want to find out if absolute differences between 2 >>> numbers/vectors are >>> > bigger than a given tolerance I would do: >>> >>> > all.equal(1,1.1,scale=1,tol= .1) >>> >>> > If I want to find out if relative differences between 2 >>> numbers/vectors are >>> > bigger than a given tolerance I would do : >>> >>> > all.equal(1,1.1,tol=.1) >>> >>> > ############################################################ >>> ###################################################################### >>> >>> > I can also do : >>> >>> > all.equal(1,3,tol=1) >>> >>> > to find out if the absolute difference is bigger than 1.But here I >>> won't be >>> > able to detect absolute differences smaller than 1 in this case,so >>> I >>> don't >>> > think that this is a good way. >>> >>> > My query is: what is the reasoning behind all.equal returning the >>> absolute >>> > difference if the tolerance >= target and relative difference if >>> tolerance >>> > < target? >>> (above, it is tol >/<= |target| ie. absolute value) >>> >>> >>> The following are desiderata / restrictions : >>> >>> 1) Relative tolerance is needed to keep things scale-invariant >>> i.e., all.equal(x, y) and all.equal(1000 * x, 1000 * y) >>> should typically be identical for (almost) all (x,y). >>> >>> ==> "the typical behavior should use relative error tolerance" >>> >>> 2) when x or y (and typically both!) are very close to zero it >>> is typically undesirable to keep relative tolerances (in the >>> boundary case, they _are_ zero exactly, and "relative error" is >>> undefined). >>> E.g., for most purposes, 3.45e-15 and 1.23e-17 should be counted as >>> equal to zero and hence to themselves. >>> >>> 1) and 2) are typically reconciled by switching from relative to absolute >>> when the arguments are close to zero (*). >>> >>> The exact cutoff at which to switch from relative to absolute >>> (or a combination of the two) is somewhat arbitrary(*2) and for >>> all.equal() has been made in the 1980's (or even slightly >>> earlier?) when all.equal() was introduced into the S language at >>> Bell labs AFAIK. Maybe John Chambers (or Rick Becker or ..., >>> but they may not read R-help) knows more. >>> *2) Then, the choice for all.equal() is in some way "least arbitrary", >>> using c = 1 in the more general tolerance >= c*|target| framework. >>> >>> *) There have been alternatives in "the (applied numerical >>> analysis / algorithm) literature" seen in published algorithms, >>> but I don't have any example ready. >>> Notably some of these alternatives are _symmetric_ in (x,y) >>> where all.equal() was designed to be asymmetric using names >>> 'target' and 'current'. >>> >>> The alternative idea is along the following thoughts: >>> >>> Assume that for "equality" we want _both_ relative and >>> absolute (e := tolerance) "equality" >>> >>> |x - y| < e (|x|+|y|)/2 (where you could use |y| or |x| >>> instead of their mean; all.equal() >>> uses |target|) >>> |x - y| < e * e1 (where e1 = 1, or e1 = 10^-7..) >>> >>> If you add the two inequalities you get >>> >>> |x - y| < e (e1 + |x+y|/2) >>> >>> as check which is a "mixture" of relative and absolute tolerance. >>> >>> With a somewhat long history, my gut feeling would nowadays >>> actually prefer this (I think with a default of e1 = e) - which >>> does treat x and y symmetrically. >>> >>> Note that convergence checks in good algorithms typically check >>> for _both_ relative and absolute difference (each with its >>> tolerance providable by the user), and the really good ones for >>> minimization do check for (approximate) gradients also being >>> close to zero - as old timers among us should have learned from >>> Doug Bates ... but now I'm really diverging. >>> >>> Last but not least some R code at the end, showing that the >>> *asymmetric* >>> nature of all.equal() may lead to somewhat astonishing (but very >>> logical and as documented!) behavior. >>> >>> Martin >>> >>> > Best Regards, >>> > Ashim >>> >>> >>> ## The "data" to use: >>>> epsQ <- lapply(seq(12,18,by=1/2), function(P) bquote(10^-.(P))); >>>> >>> names(epsQ) <- sapply(epsQ, deparse); str(epsQ) >>> List of 13 >>> $ 10^-12 : language 10^-12 >>> $ 10^-12.5: language 10^-12.5 >>> $ 10^-13 : language 10^-13 >>> $ 10^-13.5: language 10^-13.5 >>> $ 10^-14 : language 10^-14 >>> $ 10^-14.5: language 10^-14.5 >>> $ 10^-15 : language 10^-15 >>> $ 10^-15.5: language 10^-15.5 >>> $ 10^-16 : language 10^-16 >>> $ 10^-16.5: language 10^-16.5 >>> $ 10^-17 : language 10^-17 >>> $ 10^-17.5: language 10^-17.5 >>> $ 10^-18 : language 10^-18 >>> >>> str(lapply(epsQ, function(tl) all.equal(3.45e-15, 1.23e-17, tol >>>> >>> eval(tl)))) >>> List of 13 >>> $ 10^-12 : logi TRUE >>> $ 10^-12.5: logi TRUE >>> $ 10^-13 : logi TRUE >>> $ 10^-13.5: logi TRUE >>> $ 10^-14 : logi TRUE >>> $ 10^-14.5: chr "Mean relative difference: 0.9964348" >>> $ 10^-15 : chr "Mean relative difference: 0.9964348" >>> $ 10^-15.5: chr "Mean relative difference: 0.9964348" >>> $ 10^-16 : chr "Mean relative difference: 0.9964348" >>> $ 10^-16.5: chr "Mean relative difference: 0.9964348" >>> $ 10^-17 : chr "Mean relative difference: 0.9964348" >>> $ 10^-17.5: chr "Mean relative difference: 0.9964348" >>> $ 10^-18 : chr "Mean relative difference: 0.9964348" >>> >>> ## Now swap `target` and `current` : >>>> str(lapply(epsQ, function(tl) all.equal(1.23e-17, 3.45e-15, tol >>>> >>> eval(tl)))) >>> List of 13 >>> $ 10^-12 : logi TRUE >>> $ 10^-12.5: logi TRUE >>> $ 10^-13 : logi TRUE >>> $ 10^-13.5: logi TRUE >>> $ 10^-14 : logi TRUE >>> $ 10^-14.5: chr "Mean absolute difference: 3.4377e-15" >>> $ 10^-15 : chr "Mean absolute difference: 3.4377e-15" >>> $ 10^-15.5: chr "Mean absolute difference: 3.4377e-15" >>> $ 10^-16 : chr "Mean absolute difference: 3.4377e-15" >>> $ 10^-16.5: chr "Mean absolute difference: 3.4377e-15" >>> $ 10^-17 : chr "Mean relative difference: 279.4878" >>> $ 10^-17.5: chr "Mean relative difference: 279.4878" >>> $ 10^-18 : chr "Mean relative difference: 279.4878" >>> >>> >>>> >>> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide http://www.R-project.org/posti >> ng-guide.html >> and provide commented, minimal, self-contained, reproducible code. >> >> >[[alternative HTML version deleted]]